refactor(project): remove unused DataQueue implementation and CCfgFileParser
- Removed DataQueue and CCfgFileParser classes - Deleted related source files and Makefile - Updated .gitignore to exclude new directories - Modified CMakeLists.txt to add library output path - Added new memory comparison assertion macros in c_testcase.h
This commit is contained in:
parent
5ca1a439f3
commit
610a7e4008
|
@ -5,6 +5,7 @@ build
|
||||||
################ Executable program ################
|
################ Executable program ################
|
||||||
|
|
||||||
bin/
|
bin/
|
||||||
|
lib/
|
||||||
dist/
|
dist/
|
||||||
|
|
||||||
################### VSCode config ##################
|
################### VSCode config ##################
|
||||||
|
|
|
@ -5,6 +5,7 @@ project(external_interface CXX)
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
if (NOT CMAKE_CROSSCOMPILING)
|
if (NOT CMAKE_CROSSCOMPILING)
|
||||||
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
|
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/bin)
|
||||||
|
set(LIBRARY_OUTPUT_PATH ${CMAKE_SOURCE_DIR}/lib)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
# 外部接口模块文档
|
||||||
|
|
||||||
|
本文档主要描述Voix中的用于与遥测机及上位机进行通讯及相关附加功能的模块。
|
||||||
|
这些模块拆分自原host_com.cpp文件。
|
||||||
|
|
||||||
|
## 1. 构建及测试
|
||||||
|
|
||||||
|
使用cmake进行构建:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake . -B build
|
||||||
|
cmake --build build -j6
|
||||||
|
```
|
||||||
|
|
||||||
|
使用cmake及ctest进行测试:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake . -B build
|
||||||
|
cmake --build build -j6 --target test
|
||||||
|
```
|
||||||
|
|
||||||
|
或在构建完成后使用测试脚本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./scripts/unittest.py bin/test_*
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 模块公开接口
|
||||||
|
|
||||||
|
以下接口由通讯模块公开,可以在VOIX主程序中使用。
|
||||||
|
|
||||||
|
1. `void exint_init(const char* config_path, et_callback_t cb)`:模块初始化函数,此函数会读取配置文件,开启串口并启动模块所需的线程
|
||||||
|
- `config_path`:配置文件路径
|
||||||
|
- `cb`:回调函数,用于进行指令响应和遥测数据请求
|
||||||
|
2. `void (*et_callback_t)(uint32_t type, size_t len, void* data)`:回调函数类型,内部数据为指针类型的数据包仅保证在回调函数中有效。
|
||||||
|
- `type`:数据包类型
|
||||||
|
- `len`:数据包长度,对于字符串类型数据应包含后缀`\0`的长度。
|
||||||
|
- `data`:数据包数据
|
||||||
|
4. 数据包类型(宏定义):
|
||||||
|
- `ET_TYPE_TEXT`:文本,对应`const char*`类型的数据
|
||||||
|
- `ET_TYPE_AUDIO`:音频,对应`short*`类型的数据
|
||||||
|
- `ET_TYPE_COMMAND`:指令码,对应`uint8_t[6]`类型的数据
|
||||||
|
- `ET_TYPE_ALARM`:告警码,对应`AlarmData*`类型的数据
|
||||||
|
- `ET_TYPE_TELEMETRY_REQUEST`:遥测请求,对应`TelemetryRequestData*`类型的数据,需要主程序在数据包内的指针中写入对应的变量数据
|
||||||
|
5. `void exint_send(uint32_t type, size_t len, void* data)`:发送数据包,此函数是非阻塞的
|
||||||
|
- `type`:数据包类型
|
||||||
|
- `len`:数据包长度,对于字符串类型数据应包含后缀`\0`的长度。
|
||||||
|
- `data`:数据包数据
|
||||||
|
6. `void exint_finialize()`:模块销毁函数,调用后模块会终止所有内部线程,释放所有资源。
|
|
@ -154,6 +154,36 @@ extern "C"{
|
||||||
test_case_abort(1); \
|
test_case_abort(1); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
#define assert_mem_eq(expr1, expr2, size) do { \
|
||||||
|
if (memcmp((expr1), (expr2), (size)) != 0) { \
|
||||||
|
printf("assertion failed: %s == %s\n", #expr1, #expr2); \
|
||||||
|
printf("\t#0: "); \
|
||||||
|
for (int i = 0; i < (size); i++) { \
|
||||||
|
printf("%02X", ((uint8_t*)(expr1))[i]); \
|
||||||
|
} \
|
||||||
|
printf("\n\t#1: "); \
|
||||||
|
for (int i = 0; i < (size); i++) { \
|
||||||
|
printf("%02X", ((uint8_t*)(expr2))[i]); \
|
||||||
|
} \
|
||||||
|
printf("\nfile: \"%s\", line %d, in %s\n", __FILE__, __LINE__, __ASSERT_FUNCTION);\
|
||||||
|
test_case_abort(1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#define assert_mem_ne(expr1, expr2, size) do { \
|
||||||
|
if (memcmp((expr1), (expr2), (size)) == 0) { \
|
||||||
|
printf("assertion failed: %s != %s\n", #expr1, #expr2); \
|
||||||
|
printf("\t#0: "); \
|
||||||
|
for (int i = 0; i < (size); i++) { \
|
||||||
|
printf("%02X", ((uint8_t*)(expr1))[i]); \
|
||||||
|
} \
|
||||||
|
printf("\n\t#1: "); \
|
||||||
|
for (int i = 0; i < (size); i++) { \
|
||||||
|
printf("%02X", ((uint8_t*)(expr2))[i]); \
|
||||||
|
} \
|
||||||
|
printf("\nfile: \"%s\", line %d, in %s\n", __FILE__, __LINE__, __ASSERT_FUNCTION);\
|
||||||
|
test_case_abort(1); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
typedef int (*test_case)();
|
typedef int (*test_case)();
|
||||||
|
|
|
@ -7,7 +7,45 @@
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
class QueueException;
|
template <typename T>
|
||||||
|
class DataQueue;
|
||||||
|
|
||||||
|
class QueueException : public std::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QueueException(void* queue) : queue(queue) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
DataQueue<T>* GetQueue() const noexcept
|
||||||
|
{
|
||||||
|
return static_cast<DataQueue<T>*>(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
class QueueCleared : public QueueException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QueueCleared(void* queue) : QueueException(queue) {}
|
||||||
|
|
||||||
|
const char* what() const noexcept override
|
||||||
|
{
|
||||||
|
return "queue cleared";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class QueueTimeout : public QueueException
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QueueTimeout(void* queue) : QueueException(queue) {}
|
||||||
|
|
||||||
|
const char* what() const noexcept override
|
||||||
|
{
|
||||||
|
return "queue timeout";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class DataQueue {
|
class DataQueue {
|
||||||
|
@ -32,7 +70,7 @@ public:
|
||||||
{
|
{
|
||||||
m_Cond.wait(lock);
|
m_Cond.wait(lock);
|
||||||
if (epoch != m_CurrEpoch) {
|
if (epoch != m_CurrEpoch) {
|
||||||
throw QueueException(this);
|
throw QueueCleared(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
T data = std::move(m_Queue.front());
|
T data = std::move(m_Queue.front());
|
||||||
|
@ -51,9 +89,12 @@ public:
|
||||||
throw QueueTimeout(this);
|
throw QueueTimeout(this);
|
||||||
}
|
}
|
||||||
if (epoch != m_CurrEpoch) {
|
if (epoch != m_CurrEpoch) {
|
||||||
throw QueueException(this);
|
throw QueueCleared(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
T data = std::move(m_Queue.front());
|
||||||
|
m_Queue.pop_front();
|
||||||
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Empty() noexcept
|
bool Empty() noexcept
|
||||||
|
@ -85,37 +126,4 @@ private:
|
||||||
uint8_t m_CurrEpoch;
|
uint8_t m_CurrEpoch;
|
||||||
};
|
};
|
||||||
|
|
||||||
class QueueException : public std::exception
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
QueueException(void* queue) : queue(queue) {}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
DataQueue<T>* GetQueue() const noexcept
|
|
||||||
{
|
|
||||||
return static_cast<DataQueue<T>*>(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void* queue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class QueueCleared : QueueException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const char* what() const noexcept override
|
|
||||||
{
|
|
||||||
return "queue cleared";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class QueueTimeout : QueueException
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
const char* what() const noexcept override
|
|
||||||
{
|
|
||||||
return "queue timeout";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -10,7 +10,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void exint_handle_pack(uint32_t type, size_t len, union PacketData data);
|
void exint_handle_pack(uint32_t type, size_t len, void* data);
|
||||||
int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t cb);
|
int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t cb);
|
||||||
|
|
||||||
void* telemetry_host_com_thread(void* args);
|
void* telemetry_host_com_thread(void* args);
|
||||||
|
|
|
@ -41,20 +41,12 @@ struct TelemetryRequestData {
|
||||||
int app_ver_low;
|
int app_ver_low;
|
||||||
};
|
};
|
||||||
|
|
||||||
union PacketData
|
typedef void (*et_callback_t)(uint32_t, size_t, void*);
|
||||||
{
|
|
||||||
int64_t pd_integer;
|
|
||||||
double pd_float;
|
|
||||||
const char* pd_text;
|
|
||||||
void* pd_pointer;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*et_callback_t)(uint32_t, size_t, union PacketData);
|
|
||||||
|
|
||||||
EXTERN_INTERFACE_PUBLIC
|
EXTERN_INTERFACE_PUBLIC
|
||||||
int exint_init(const char* config_path, et_callback_t cb);
|
int exint_init(const char* config_path, et_callback_t cb);
|
||||||
EXTERN_INTERFACE_PUBLIC
|
EXTERN_INTERFACE_PUBLIC
|
||||||
void exint_send(uint32_t type, size_t len, union PacketData data);
|
void exint_send(uint32_t type, size_t len, void* data);
|
||||||
EXTERN_INTERFACE_PUBLIC
|
EXTERN_INTERFACE_PUBLIC
|
||||||
void exint_finialize();
|
void exint_finialize();
|
||||||
|
|
||||||
|
|
|
@ -1,263 +0,0 @@
|
||||||
//bb.cpp
|
|
||||||
|
|
||||||
#include <cstdio>
|
|
||||||
#include <cstring>
|
|
||||||
#include <fstream>
|
|
||||||
#include <cerrno>
|
|
||||||
#include <sstream>
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "CCfgFileParser.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
static inline bool istab(int c) { return (c == '\t'); }
|
|
||||||
|
|
||||||
static inline char *strltrim(char *str) {
|
|
||||||
while (isspace(*str) || istab(*str)) {
|
|
||||||
++str;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline char *strrtrim(char *str) {
|
|
||||||
int len = strlen(str) - 1;
|
|
||||||
while (isspace(str[len]) || istab(str[len])) {
|
|
||||||
str[len--] = '\0';
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// Construction/Destruction
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
int CCfgFileParser::parseFile(const char *lpszFilename) {
|
|
||||||
using std::string;
|
|
||||||
std::ifstream in1(lpszFilename);
|
|
||||||
|
|
||||||
if (!in1.is_open()) return errno;
|
|
||||||
|
|
||||||
char line[2048];
|
|
||||||
char *pline;
|
|
||||||
bool bInSection = false;
|
|
||||||
SECTION_CONTENT *pSC = NULL;
|
|
||||||
string strSection;
|
|
||||||
std::pair<string, string> pairKeyValue;
|
|
||||||
|
|
||||||
m_error_line = 0;
|
|
||||||
m_content.clear();
|
|
||||||
pSC = &m_content["default"];
|
|
||||||
bInSection = true;
|
|
||||||
string base64str("");
|
|
||||||
string mystr("");
|
|
||||||
while (!in1.eof()) {
|
|
||||||
in1.getline(line, sizeof(line));
|
|
||||||
|
|
||||||
if (line[strlen(line)] != '\n')
|
|
||||||
mystr += line + string("\n");
|
|
||||||
else
|
|
||||||
mystr += line;
|
|
||||||
|
|
||||||
}
|
|
||||||
in1.close();
|
|
||||||
|
|
||||||
stringstream in;
|
|
||||||
in.str(mystr);
|
|
||||||
|
|
||||||
while (!in.eof()) { /*if(base64str.size() > sizeof(line))
|
|
||||||
{
|
|
||||||
printf("error in config parser!\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(line, base64str.c_str(), base64str.size());
|
|
||||||
*/
|
|
||||||
in.getline(line, sizeof(line));
|
|
||||||
pline = line;
|
|
||||||
++m_error_line;
|
|
||||||
pline = strltrim(pline);
|
|
||||||
if (pline[0] == '\0') continue; //white line, skip
|
|
||||||
if (pline[0] == m_chCommentMark) continue; //comment line, skip
|
|
||||||
if (bInSection) {
|
|
||||||
//is new-section begin?
|
|
||||||
if (pline[0] == m_chSectionBMark && extractSection(pline, strSection)) {
|
|
||||||
pSC = &m_content[strSection];
|
|
||||||
}
|
|
||||||
else if (extractKeyValue(pline, pairKeyValue)) {
|
|
||||||
//key-value pair
|
|
||||||
pSC->insert(pairKeyValue);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//in.close();
|
|
||||||
return SYNTAX_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { //NOT in section
|
|
||||||
//is a valid section?
|
|
||||||
if (extractSection(pline, strSection)) {
|
|
||||||
pSC = &m_content[strSection];
|
|
||||||
bInSection = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
//in.close();
|
|
||||||
return SYNTAX_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// in.close();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool CCfgFileParser::getValue(const std::string &strSection,
|
|
||||||
const std::string &strKey, const char * &Value) const {
|
|
||||||
FILE_CONTENT::const_iterator it;
|
|
||||||
|
|
||||||
if ((it = m_content.find(strSection)) != m_content.end()) {
|
|
||||||
SECTION_CONTENT::const_iterator p;
|
|
||||||
const SECTION_CONTENT §ion = (*it).second;//m_content[strSection];
|
|
||||||
if ((p = section.find(strKey)) != section.end()) {
|
|
||||||
Value = ((*p).second).c_str();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_bShowError)
|
|
||||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCfgFileParser::getValue(const std::string &strKey, const char * &pValue) const {
|
|
||||||
return getValue("default", strKey, pValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCfgFileParser::getIntValue(const std::string &strSection,
|
|
||||||
const std::string& strKey, long& Value) const {
|
|
||||||
const char* pstr;
|
|
||||||
if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0)
|
|
||||||
{
|
|
||||||
if (strlen(pstr) > 0)
|
|
||||||
{
|
|
||||||
Value = atol(pstr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (m_bShowError)
|
|
||||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCfgFileParser::getIntValue(const std::string &strKey, long &Value) const {
|
|
||||||
return getIntValue("default", strKey, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCfgFileParser::getDoubleValue(const std::string &strSection,
|
|
||||||
const std::string &strKey, double &Value) const {
|
|
||||||
const char *pstr;
|
|
||||||
if (getValue(strSection, strKey, pstr) && strlen(pstr) > 0)
|
|
||||||
{
|
|
||||||
Value = atof(pstr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (m_bShowError)
|
|
||||||
fprintf(stderr, "***Error: fail to read [%s]:%s\n", strSection.c_str(), strKey.c_str());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CCfgFileParser::getDoubleValue(const std::string &strKey, double &Value) const {
|
|
||||||
return getDoubleValue("default", strKey, Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Description: Extract section name
|
|
||||||
* Parameters: line[IN]---A string line to be parsed
|
|
||||||
* strSection[OUT]---Section name
|
|
||||||
*
|
|
||||||
* Return Value: if section name is in the line return true,or return false
|
|
||||||
*/
|
|
||||||
bool CCfgFileParser::extractSection(char *line, std::string &strSection) {
|
|
||||||
char *tmp;
|
|
||||||
if (line[0] == m_chSectionBMark) {
|
|
||||||
if ((tmp = strchr(++line, m_chSectionEMark)) != NULL) {
|
|
||||||
*tmp = '\0';
|
|
||||||
strSection = line;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Description: Parse a record line into a std:pair as key and value
|
|
||||||
* Parameters: line[IN]---A string to be parsed
|
|
||||||
* pairKeyValue[OUT]---Parsing result
|
|
||||||
*
|
|
||||||
* Return Value: If parse successfully return true,or return false
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool CCfgFileParser::extractKeyValue(char *line,
|
|
||||||
std::pair<std::string, std::string> &pairKeyValue) {
|
|
||||||
char *tmp;
|
|
||||||
if ((tmp = strchr(line, m_chRecordEMark)) != NULL || (tmp = strchr(line, '\r')) != NULL ||
|
|
||||||
(tmp = strchr(line, '='))) {
|
|
||||||
if (*tmp == '=')
|
|
||||||
tmp = line + strlen(line); // tmp++;
|
|
||||||
*tmp = '\0'; //ignore content after ';'(the RecordEMark)
|
|
||||||
if ((tmp = strchr(line, '=')) != NULL) {
|
|
||||||
*tmp++ = '\0';
|
|
||||||
tmp = strltrim(tmp);
|
|
||||||
tmp = strrtrim(tmp);
|
|
||||||
line = strrtrim(line);
|
|
||||||
|
|
||||||
pairKeyValue.first = line;
|
|
||||||
pairKeyValue.second = tmp;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *CCfgFileParser::getErrorString(int err) {
|
|
||||||
static char buf[100];
|
|
||||||
if (err == SYNTAX_ERROR) {
|
|
||||||
sprintf(buf, "configuration file format is invalid at line %d", m_error_line);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return strerror(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CCfgFileParser::printContent() {
|
|
||||||
using std::cout;
|
|
||||||
using std::endl;
|
|
||||||
FILE_CONTENT::const_iterator pf;
|
|
||||||
SECTION_CONTENT::const_iterator ps;
|
|
||||||
for (pf = m_content.begin(); pf != m_content.end(); ++pf) {
|
|
||||||
cout << "section:" << (*pf).first << endl;
|
|
||||||
const SECTION_CONTENT &sc = (*pf).second;
|
|
||||||
for (ps = sc.begin(); ps != sc.end(); ++ps) {
|
|
||||||
cout << '\t' << (*ps).first << "=" << (*ps).second << endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在库中定义一个工厂函数 createParser
|
|
||||||
extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser() {
|
|
||||||
return new CCfgFileParser(); // 在工厂函数中调用构造函数创建对象并返回指针
|
|
||||||
}
|
|
||||||
|
|
||||||
// 在库中定义一个销毁函数 deleteParser
|
|
||||||
|
|
||||||
extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser) {
|
|
||||||
// 在销毁函数中调用析构函数销毁对象
|
|
||||||
delete parser;
|
|
||||||
}
|
|
|
@ -1,78 +0,0 @@
|
||||||
#if !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_)
|
|
||||||
#define AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#pragma warning(disable:4786)
|
|
||||||
#pragma warning(disable:4503)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
class __attribute__((visibility("default"))) CCfgFileParser
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit CCfgFileParser(bool base64 = false,
|
|
||||||
char chSectionBMark = '[',
|
|
||||||
char chSectionEMark = ']',
|
|
||||||
char chRecordEMark = ';', //record end-mark
|
|
||||||
char chCommentMark = '#'
|
|
||||||
)
|
|
||||||
:m_base64(base64), m_chSectionBMark(chSectionBMark), m_chSectionEMark(chSectionEMark),
|
|
||||||
m_chRecordEMark(chRecordEMark), m_chCommentMark(chCommentMark), m_bShowError(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~CCfgFileParser() {}
|
|
||||||
|
|
||||||
typedef std::map<std::string, std::string> SECTION_CONTENT;
|
|
||||||
typedef std::map<std::string, SECTION_CONTENT > FILE_CONTENT;
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_base64;
|
|
||||||
enum{
|
|
||||||
SYNTAX_ERROR = 0x100,
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
bool m_bShowError;
|
|
||||||
const char* getErrorString(int err);
|
|
||||||
int parseFile(const char* lpszFilename);
|
|
||||||
int sections() const { return m_content.size(); }
|
|
||||||
|
|
||||||
FILE_CONTENT::const_iterator sectionBegin() const { return m_content.begin(); }
|
|
||||||
FILE_CONTENT::const_iterator sectionEnd() const { return m_content.end(); }
|
|
||||||
|
|
||||||
//return empty-string if no corresponding value presented.
|
|
||||||
bool getValue(const std::string& strSection, const std::string& strKey, const char *&Value) const;
|
|
||||||
bool getValue(const std::string& strKey, const char *&Value) const;
|
|
||||||
bool getIntValue(const std::string& strSection, const std::string& strKey, long &pValue) const;
|
|
||||||
bool getIntValue(const std::string& strKey, long &Value) const;
|
|
||||||
bool getDoubleValue(const std::string& strSection, const std::string& strKey, double &Value) const;
|
|
||||||
bool getDoubleValue(const std::string& strKey, double &Value) const;
|
|
||||||
void printContent();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool extractSection(char* line, std::string& strSection);
|
|
||||||
bool extractKeyValue(char* line, std::pair<std::string, std::string>& pairKeyValue);
|
|
||||||
|
|
||||||
private:
|
|
||||||
FILE_CONTENT m_content;
|
|
||||||
|
|
||||||
char m_chSectionBMark;
|
|
||||||
char m_chSectionEMark;
|
|
||||||
char m_chRecordEMark;
|
|
||||||
char m_chCommentMark;
|
|
||||||
int m_error_line;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" __attribute__((visibility("default"))) CCfgFileParser* createParser();
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" __attribute__((visibility("default"))) void deleteParser(CCfgFileParser* parser);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // !defined(AFX_CFGFILEPARSERGENERATOR_H__AAF8F913_7694_4A69_A05F_57A1A1887CA1__INCLUDED_)
|
|
|
@ -1,44 +0,0 @@
|
||||||
INCS = log.h CCfgFileParser.h
|
|
||||||
SRCS = CCfgFileParser.cpp log.cpp dataqueue.cpp
|
|
||||||
CXX = g++
|
|
||||||
AR = ar
|
|
||||||
EXEC_SO = libqueuelog.so
|
|
||||||
EXEC_A = libqueuelog.a
|
|
||||||
EXEC_O = libqueuelog.o
|
|
||||||
|
|
||||||
# 输出目录
|
|
||||||
OUTPUT_LIB_DIR = ../../libs/
|
|
||||||
OUTPUT_INCLUDE_DIR=../../includes/
|
|
||||||
|
|
||||||
|
|
||||||
ifdef DEBUG_VERSION
|
|
||||||
CFLAGS := -DMY_DEBUG -fvisibility=hidden -g -Wall -fPIC -shared -std=c++11 -Wl,--as-needed
|
|
||||||
else
|
|
||||||
CFLAGS := -fvisibility=hidden -g3 -O2 -Wall -fPIC -shared -std=c++11 -Wl,--as-needed
|
|
||||||
endif
|
|
||||||
|
|
||||||
LFLAGS1 = -lpthread
|
|
||||||
|
|
||||||
OBJS = $(SRCS:.cpp=.o)
|
|
||||||
|
|
||||||
all: $(EXEC_SO) $(EXEC_A)
|
|
||||||
|
|
||||||
$(EXEC_SO): $(OBJS)
|
|
||||||
$(CXX) -o $(EXEC_SO) $(OBJS) $(CFLAGS) $(LFLAGS1)
|
|
||||||
|
|
||||||
$(EXEC_A): $(OBJS)
|
|
||||||
$(AR) rcs $(EXEC_A) $(OBJS)
|
|
||||||
mkdir -p $(OUTPUT_LIB_DIR)
|
|
||||||
mkdir -p $(OUTPUT_INCLUDE_DIR)
|
|
||||||
mv $(EXEC_A) $(OUTPUT_LIB_DIR)
|
|
||||||
mv $(EXEC_SO) $(OUTPUT_LIB_DIR)
|
|
||||||
cp -u *.h $(OUTPUT_INCLUDE_DIR)
|
|
||||||
find . -name "*.d" -type f -print -exec rm -rf {} \;
|
|
||||||
@echo "Compile successfully! result-->" $(OUTPUT_LIB_DIR)
|
|
||||||
|
|
||||||
%.o: %.cpp
|
|
||||||
$(CXX) -o $@ -c $< $(CFLAGS)
|
|
||||||
|
|
||||||
.PHONY: clean
|
|
||||||
clean:
|
|
||||||
rm -f $(EXEC_SO) $(EXEC_A) $(EXEC_O) $(OBJS)
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
#rm -f *.so *.o
|
|
||||||
CUR=$(basename `pwd`)
|
|
||||||
echo $CUR
|
|
||||||
mkdir -p ../../_backup
|
|
||||||
tar --exclude=*.so --exclude=*.a --exclude=*.o --exclude=*.d --exclude=./.vs --exclude=*.git* --exclude=*.swp -czvf ../../_backup/${CUR}-`date +"%Y.%m.%d-%H.%M"`.tar.gz ../${CUR}/*
|
|
||||||
#tar -czvf ../_backup/${CUR}-`date +"%Y.%m.%d-%H.%M"`.tar.gz ../${CUR}
|
|
||||||
curDate=$(date +"%Y.%m.%d %H:%M:%S")
|
|
||||||
echo backup done!@${curDate}
|
|
||||||
|
|
||||||
|
|
|
@ -1,537 +0,0 @@
|
||||||
//#pragma once
|
|
||||||
#include <time.h>
|
|
||||||
#include "dataqueue.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#define BLOCK_PADDING_SIZE 64 //bytes
|
|
||||||
#define HEADER_BYTES 16//remain: block-bytes: 8 bytes int64_t + data bytes: 8bytes int64_t
|
|
||||||
#define CHECK_QUEUE_ERR 1
|
|
||||||
#define myMax(x,y) ((x)>(y)?(x):(y))
|
|
||||||
|
|
||||||
typedef void* voidPtr;
|
|
||||||
static char g_strDQCurTime[50] = "";
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
inline char* GetCurTimeStr(char* strBuf, int iBufSize)// g_strDQCurTime
|
|
||||||
{
|
|
||||||
time_t tt;
|
|
||||||
tt = time(NULL);
|
|
||||||
strftime(strBuf, iBufSize, "%Y.%m.%d %H:%M:%S", localtime(&tt));//gener string with format:"YYYY-MM-DD hh:mm:ss"
|
|
||||||
return strBuf;
|
|
||||||
}
|
|
||||||
#define DATA_QUEUE_RETAIN_BLOCK_CNT 4
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
DataQueue::DataQueue(int64_t iSizeInKB, int64_t iMaxBlockSize, bool bUseMutex, int iReadThreadCnt)
|
|
||||||
{
|
|
||||||
m_pDataBuf = NULL;
|
|
||||||
m_bUseMutex = bUseMutex;
|
|
||||||
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_init(&m_BufMutex, NULL);
|
|
||||||
InitQueue(iSizeInKB, iMaxBlockSize, iReadThreadCnt);//KB
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
DataQueue::~DataQueue()
|
|
||||||
{
|
|
||||||
if (m_pDataBuf != NULL)
|
|
||||||
free((void*)m_pDataBuf);
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_destroy(&m_BufMutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
int DataQueue::InitQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt)//KB
|
|
||||||
{
|
|
||||||
if (m_pDataBuf != NULL)
|
|
||||||
free((void*)m_pDataBuf);
|
|
||||||
m_pDataBuf = NULL;
|
|
||||||
m_iMaxBlockByte = iMaxBlockBytes;
|
|
||||||
m_iReservedBlockNum = iReadThreadCnt + DATA_QUEUE_RETAIN_BLOCK_CNT;
|
|
||||||
m_iReservedBufBytes = m_iMaxBlockByte * m_iReservedBlockNum; //4 times of m_iMaxBlockByte
|
|
||||||
int64_t iTotalByes = 0;
|
|
||||||
if (iTotalKB4QueueBuf > 0)
|
|
||||||
{
|
|
||||||
iTotalByes = iTotalKB4QueueBuf * 1024 + 2 * HEADER_BYTES + m_iReservedBufBytes; //KB;
|
|
||||||
m_pDataBuf = (uint8_t*)malloc(iTotalByes); //for safe sake in case of over step the border
|
|
||||||
if (m_pDataBuf == NULL)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
|
||||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
|
||||||
fprintf(stderr, "***Error: fail to malloc for data queue, mem:%ld @line:%d %s\n", iTotalKB4QueueBuf, __LINE__, g_strDQCurTime);
|
|
||||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
|
||||||
fflush(stderr);
|
|
||||||
exit(4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_iFreeBytes = m_iQueueBufBytes = iTotalByes;
|
|
||||||
ResetDataQueue();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
void DataQueue::ResetDataQueue()
|
|
||||||
{
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_lock(&m_BufMutex);
|
|
||||||
m_iBufOutPos = m_iBufInPos = 0;
|
|
||||||
m_iRcvBlocks = 0;
|
|
||||||
m_iRcvBytes = 0;
|
|
||||||
m_iProcBlocks = 0;
|
|
||||||
m_iEmptyTimes = 0;
|
|
||||||
m_iFullTimes = 0;
|
|
||||||
m_iPaddingBlocks = m_iProcPaddingBlocks = 0;
|
|
||||||
m_iFreeBytes = m_iQueueBufBytes;
|
|
||||||
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
int64_t DataQueue::GetBufBytes()
|
|
||||||
{//Get buf size
|
|
||||||
int64_t iBytes;
|
|
||||||
iBytes = m_iQueueBufBytes - m_iReservedBufBytes;
|
|
||||||
if (iBytes < 0)
|
|
||||||
iBytes = 0;
|
|
||||||
return iBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
int64_t DataQueue::GetQueueFreeBytes()
|
|
||||||
{
|
|
||||||
//int64_t iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos) ) );
|
|
||||||
int64_t iFreeBytes;
|
|
||||||
|
|
||||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos)));
|
|
||||||
iFreeBytes -= m_iReservedBufBytes;
|
|
||||||
if (iFreeBytes < 0)//iFreeBytes never is 0 because of m_iReservedBufBytes, unless the beginning state where m_iBufOutPos and m_iBufInPos are same
|
|
||||||
iFreeBytes = 0;
|
|
||||||
|
|
||||||
return iFreeBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
int64_t DataQueue::GetFreeBytes()
|
|
||||||
{
|
|
||||||
return GetQueueFreeBytes();
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
inline bool DataQueue::CanRcv(int iNeedBytes)
|
|
||||||
{
|
|
||||||
bool bCanRcv;
|
|
||||||
m_iMaxBlockByte = iNeedBytes > m_iMaxBlockByte ? iNeedBytes : m_iMaxBlockByte;
|
|
||||||
m_iReservedBufBytes = m_iMaxBlockByte * m_iReservedBlockNum; //4<><34><EFBFBD><EFBFBD>m_iMaxBlockByte
|
|
||||||
|
|
||||||
bCanRcv = (GetQueueFreeBytes() >= iNeedBytes);
|
|
||||||
|
|
||||||
return bCanRcv;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
bool DataQueue::IsFull()
|
|
||||||
{
|
|
||||||
//---- 这种判断方式,可能存在错误,即:期间m_iBufOutPos到尾部,折回到队列开头,变得小于m_iBufInPos
|
|
||||||
//int iFreeBytes = (m_iBufInPos < m_iBufOutPos ? (m_iBufOutPos - m_iBufInPos) : (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)));//
|
|
||||||
bool bFull;
|
|
||||||
int64_t iFreeBytes;
|
|
||||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : ((m_iBufOutPos - m_iBufInPos)));
|
|
||||||
bFull = (iFreeBytes <= m_iReservedBufBytes);
|
|
||||||
// if( bFull )
|
|
||||||
// printf("dataqueue is full, size:%ld free:%ld - %ld < retain:%ld in:%ld out:%ld\n",
|
|
||||||
// m_iQueueBufBytes,iFreeBytes, GetFreeBytes(),m_iReservedBufBytes,m_iBufInPos,m_iBufOutPos );
|
|
||||||
return bFull;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
bool DataQueue::IsEmpty()
|
|
||||||
{
|
|
||||||
return (m_iBufInPos == m_iBufOutPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
int64_t DataQueue::EnQueue(void* e, int64_t iDataBytes, void* extradata, int64_t iExtraDataBytes, void* extradata2, int64_t iExtraDataBytes2)
|
|
||||||
{ // >=0 for normal & success,
|
|
||||||
//<0: error
|
|
||||||
int64_t iBlockBytes;
|
|
||||||
void* pWritePos = NULL;
|
|
||||||
int64_t iPadding = 0;
|
|
||||||
if (iDataBytes < 0 || iExtraDataBytes < 0 || iExtraDataBytes2 < 0)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "iDataBytes %ld iExtraDataBytes %ld iExtraDataBytes %ld\n",
|
|
||||||
iDataBytes, iExtraDataBytes, iExtraDataBytes2);
|
|
||||||
fflush(stderr);
|
|
||||||
throw __LINE__;
|
|
||||||
}
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_lock(&m_BufMutex);
|
|
||||||
|
|
||||||
int64_t iTotalDataBytes = iDataBytes + iExtraDataBytes + iExtraDataBytes2;
|
|
||||||
#if CHECK_QUEUE_ERR
|
|
||||||
CheckQueue(__LINE__, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
iBlockBytes = (((iTotalDataBytes + 7) >> 3) << 3)//8<>ı<EFBFBD><C4B1><EFBFBD>
|
|
||||||
+ HEADER_BYTES
|
|
||||||
+ BLOCK_PADDING_SIZE;// 32
|
|
||||||
|
|
||||||
if (!CanRcv(iBlockBytes))
|
|
||||||
{
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
return QUEUE_IS_FULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_iBufInPos >= m_iBufOutPos)
|
|
||||||
{
|
|
||||||
if (m_iBufInPos + iBlockBytes > m_iQueueBufBytes)
|
|
||||||
{//create a padding block
|
|
||||||
*((int64_t*)(m_pDataBuf + m_iBufInPos)) = m_iQueueBufBytes - m_iBufInPos; //m_iQueueBufBytes: the next block is at the begining of the buf
|
|
||||||
*((int64_t*)(m_pDataBuf + m_iBufInPos + sizeof(int64_t))) = 0;
|
|
||||||
//m_iRcvBlocks++;
|
|
||||||
//printf("+iBlockBytes:%d, iDataByte:%d\n", m_iQueueBufBytes - m_iBufInPos, 0);
|
|
||||||
m_iPaddingBlocks++;
|
|
||||||
iPadding++;
|
|
||||||
m_iBufInPos = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if CHECK_QUEUE_ERR
|
|
||||||
CheckQueue(__LINE__, iBlockBytes);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
pWritePos = m_pDataBuf + m_iBufInPos;
|
|
||||||
*((int64_t*)pWritePos) = iBlockBytes;
|
|
||||||
*((int64_t*)(pWritePos + sizeof(int64_t))) = iTotalDataBytes;
|
|
||||||
|
|
||||||
memcpy(pWritePos + HEADER_BYTES, e, iDataBytes);
|
|
||||||
|
|
||||||
if (extradata && iExtraDataBytes > 0)
|
|
||||||
memcpy(pWritePos + HEADER_BYTES + iDataBytes, extradata, iExtraDataBytes);//iExtraDataBytes
|
|
||||||
|
|
||||||
if (extradata2 && iExtraDataBytes2 > 0)
|
|
||||||
memcpy(pWritePos + HEADER_BYTES + iDataBytes + iExtraDataBytes, extradata2, iExtraDataBytes2);//iExtraDataBytes
|
|
||||||
|
|
||||||
m_iRcvBlocks++;
|
|
||||||
m_iRcvBytes += iTotalDataBytes;
|
|
||||||
m_iBufInPos = (m_iBufInPos + iBlockBytes) % m_iQueueBufBytes;
|
|
||||||
|
|
||||||
//#ifdef MY_DEBUG
|
|
||||||
// printf("+iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
|
|
||||||
return iTotalDataBytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
#ifdef ARM_VERSION //NO_PORN_FUNC
|
|
||||||
#define THERE_ARE_CONCURRENT_DEQUEUE_OP 1
|
|
||||||
#else
|
|
||||||
#define THERE_ARE_CONCURRENT_DEQUEUE_OP 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int64_t DataQueue::DeQueue(void** e)
|
|
||||||
{//return value: Bytes, >0 if sucess, =0 no data, < 0 error. No data copy, only return the pointer of data area
|
|
||||||
void* p;
|
|
||||||
int iBlockBytes, iDataBytes;
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
{
|
|
||||||
pthread_mutex_lock(&m_BufMutex);
|
|
||||||
#if CHECK_QUEUE_ERR
|
|
||||||
CheckQueue(__LINE__, 0);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (IsEmpty())
|
|
||||||
{
|
|
||||||
//#ifdef MY_DEBUG
|
|
||||||
// m_iEmptyTimes++;
|
|
||||||
// if ( m_iEmptyTimes <5 || ( m_iEmptyTimes % 50 == 0) )
|
|
||||||
// {
|
|
||||||
// printf("***Block Queue IsEmpty %1dth: m_iBufInPos=%lu, m_iBufOutPos=%lu, m_iQueueBufBytes=%lu, m_iReservedBufBytes=%lu\n",
|
|
||||||
// m_iEmptyTimes, m_iBufInPos, m_iBufOutPos, m_iQueueBufBytes, m_iReservedBufBytes); //<2F>ճ<EFBFBD>4<EFBFBD><34>
|
|
||||||
// fflush(stdout);
|
|
||||||
// }
|
|
||||||
//#endif
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
return EMPTY_QUEUE_NO_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = m_pDataBuf + m_iBufOutPos;
|
|
||||||
iBlockBytes = *((int64_t*)p);
|
|
||||||
iDataBytes = *((int64_t*)(p + sizeof(int64_t)));
|
|
||||||
//int iDataBytes = *((int*)(p + sizeof(int)));
|
|
||||||
m_iBufOutPos = (m_iBufOutPos + iBlockBytes) % m_iQueueBufBytes;
|
|
||||||
//#ifdef MY_DEBUG
|
|
||||||
// printf("-iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
if (iDataBytes > 0)//not pading block
|
|
||||||
{
|
|
||||||
m_iProcBlocks++;
|
|
||||||
*e = (void*)(p + HEADER_BYTES);
|
|
||||||
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
return iDataBytes;
|
|
||||||
}
|
|
||||||
else//padding block
|
|
||||||
{
|
|
||||||
m_iProcPaddingBlocks++;
|
|
||||||
if (IsEmpty())
|
|
||||||
{
|
|
||||||
//printf("CSegmentPool IsEmpty\n");
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return EMPTY_QUEUE_NO_DATA;
|
|
||||||
}
|
|
||||||
p = m_pDataBuf + m_iBufOutPos;
|
|
||||||
iBlockBytes = *((int64_t*)p);
|
|
||||||
iDataBytes = *((int64_t*)(p + sizeof(int64_t)));
|
|
||||||
//#ifdef MY_DEBUG
|
|
||||||
// printf("-iBlockBytes:%d, iDataByte:%d\n", iBlockBytes, iDataBytes);
|
|
||||||
//#endif
|
|
||||||
m_iBufOutPos = (m_iBufOutPos + iBlockBytes) % m_iQueueBufBytes;
|
|
||||||
|
|
||||||
#if CHECK_QUEUE_ERR
|
|
||||||
if (m_bUseMutex)
|
|
||||||
CheckQueue(__LINE__, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (iDataBytes > 0)//not pading block
|
|
||||||
{
|
|
||||||
m_iProcBlocks++;
|
|
||||||
*e = (void*)(p + HEADER_BYTES);
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
return iDataBytes;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{//pading block
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
m_iProcPaddingBlocks++;
|
|
||||||
char strMsg[200];
|
|
||||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
|
||||||
sprintf(strMsg, "***Error in DeQueue: 2 successive padding block!@line %d %s\n", __LINE__, g_strDQCurTime);
|
|
||||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
|
||||||
fprintf(stderr, "%s", strMsg);
|
|
||||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
|
||||||
fflush(stderr);
|
|
||||||
exit(0);
|
|
||||||
return EMPTY_QUEUE_NO_DATA;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if THERE_ARE_CONCURRENT_DEQUEUE_OP
|
|
||||||
if (m_bUseMutex)
|
|
||||||
pthread_mutex_unlock(&m_BufMutex);
|
|
||||||
#endif
|
|
||||||
char strMsg[200];
|
|
||||||
GetCurTimeStr(g_strDQCurTime, sizeof(g_strDQCurTime));
|
|
||||||
sprintf(strMsg, "***Error in DeQueue: @line %d %s\n", __LINE__, g_strDQCurTime);
|
|
||||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
|
||||||
fprintf(stderr, "%s", strMsg);
|
|
||||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
|
||||||
fflush(stderr);
|
|
||||||
exit(0);
|
|
||||||
return EMPTY_QUEUE_NO_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
void DataQueue::OutPutStatus(char* strBuf, int iBufLen)
|
|
||||||
{
|
|
||||||
int iLen = iBufLen, iStrLen;
|
|
||||||
char* p = strBuf;
|
|
||||||
snprintf(p, iLen, "m_iBufOutPos = % ld, m_iBufInPos = % ld, m_iFreeBytes = % ld, m_iQueueBufBytes = % ld, m_iRcvBlocks = % ld, m_iRcvBytes = % ld\n",
|
|
||||||
m_iBufOutPos, m_iBufInPos, m_iFreeBytes, m_iQueueBufBytes, m_iRcvBlocks, m_iRcvBytes);
|
|
||||||
iStrLen = strlen(p);
|
|
||||||
p += iStrLen;
|
|
||||||
iLen -= iStrLen;
|
|
||||||
|
|
||||||
snprintf(p, iLen, "\m_iProcBlocks=%ld, m_iPaddingBlocks=%ld, m_iProcPaddingBlocks=%ld, m_iMaxBlockByte=%ld, m_iReservedBufBytes=%ld, m_iReservedBlockNum=%ld,m_iEmptyTimes=%ld, m_iFullTimes=%ld\n",
|
|
||||||
m_iProcBlocks, m_iPaddingBlocks, m_iProcPaddingBlocks, m_iMaxBlockByte, m_iReservedBufBytes, m_iReservedBlockNum, m_iEmptyTimes, m_iFullTimes);
|
|
||||||
iStrLen = strlen(p);
|
|
||||||
p += iStrLen;
|
|
||||||
iLen -= iStrLen;
|
|
||||||
}
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
bool DataQueue::CheckQueue(int iLineNo, int iNeedBytes)
|
|
||||||
{
|
|
||||||
int64_t iFreeBytes;
|
|
||||||
int iErr = 0;
|
|
||||||
//int iFreeBytes = (m_iBufInPos < m_iBufOutPos ? (m_iBufOutPos - m_iBufInPos) : (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) );//
|
|
||||||
|
|
||||||
iFreeBytes = (m_iBufInPos >= m_iBufOutPos ? (m_iQueueBufBytes - (m_iBufInPos - m_iBufOutPos)) : (m_iBufOutPos - m_iBufInPos));
|
|
||||||
if (m_iBufOutPos < 0)
|
|
||||||
iErr |= 0x1;
|
|
||||||
if (m_iBufInPos < 0)
|
|
||||||
iErr |= 0x2;
|
|
||||||
if (iFreeBytes < (m_iReservedBlockNum - 2) * m_iMaxBlockByte)
|
|
||||||
iErr |= 0x4;
|
|
||||||
if (iFreeBytes < iNeedBytes)
|
|
||||||
iErr |= 0x8;
|
|
||||||
|
|
||||||
if (m_bUseMutex && (m_iProcBlocks == m_iRcvBlocks)
|
|
||||||
&& (m_iPaddingBlocks == m_iProcPaddingBlocks)
|
|
||||||
&& (m_iBufOutPos != m_iBufInPos))
|
|
||||||
iErr |= 0x10;
|
|
||||||
if (iErr)
|
|
||||||
{
|
|
||||||
char strMsg[1000];
|
|
||||||
char strInfo[1000];
|
|
||||||
OutPutStatus(strMsg, sizeof(strMsg));
|
|
||||||
snprintf(strInfo, sizeof(strInfo), "******QueueError %d @line %d, iFreeBytes=%ld , iNeedBytes=%d:\n%s \n",
|
|
||||||
iErr, iLineNo, iFreeBytes, iNeedBytes, strMsg);
|
|
||||||
|
|
||||||
FILE* fp = fopen("err.log", "a+");
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
fprintf(fp, "%s\n", strInfo);
|
|
||||||
fflush(fp);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
|
||||||
fprintf(stderr, "%s\n", strInfo);
|
|
||||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
|
||||||
fflush(stderr);
|
|
||||||
//throw __LINE__;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenDataQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt)
|
|
||||||
{
|
|
||||||
//DataQueue* p = new DataQueue(iTotalKB4QueueBuf, iMaxBlockBytes, bConcurrent);//bUseMutex = bConcurrent
|
|
||||||
DataQueue* p = new DataQueue(iTotalKB4QueueBuf, iMaxBlockBytes, true);//bUseMutex = true
|
|
||||||
return (void*)p;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
extern "C" bool __attribute__((visibility("default"))) GetDataQueueInfo(void* pQueue, int64_t iSize[5])
|
|
||||||
{//return the total data blocks, and set the buf with info string
|
|
||||||
int64_t iFreeBytes, iBufBytes;
|
|
||||||
DataQueue* p = (DataQueue*)pQueue;
|
|
||||||
if (!pQueue)
|
|
||||||
return false;
|
|
||||||
iSize[0] = p->GetBufBytes();
|
|
||||||
iSize[1] = p->GetFreeBytes();
|
|
||||||
iSize[2] = p->GetTotalRcvBlockCnt();
|
|
||||||
iSize[3] = p->GetProcBlockCnt();
|
|
||||||
iSize[4] = p->GetBlockCnt();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------
|
|
||||||
#define LOG_QUEUE_INFO 0
|
|
||||||
extern "C" int64_t __attribute__((visibility("default"))) EnDataQueue(void* pQueue, void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2)
|
|
||||||
{// int DataQueue::EnQueue(void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2)
|
|
||||||
int64_t iRet =0;
|
|
||||||
if (pQueue)
|
|
||||||
{
|
|
||||||
#if LOG_QUEUE_INFO
|
|
||||||
char strBuf[500];
|
|
||||||
char strBuf2[500];
|
|
||||||
FILE* fp = NULL;
|
|
||||||
|
|
||||||
snprintf(strBuf, sizeof(strBuf), "queue%p.log", pQueue);
|
|
||||||
fp = fopen(strBuf, "a+");
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
snprintf(strBuf, sizeof(strBuf), "EnQueue1: iDataBytes=%ld, extradata1=%ld, extradata2=%ld\n",
|
|
||||||
iDataBytes, iExtraDataBytes1, iExtraDataBytes2);
|
|
||||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
|
||||||
fprintf(fp, "%s%s", strBuf, strBuf2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
iRet = ((DataQueue*)pQueue)->EnQueue(e, iDataBytes, extradata1, iExtraDataBytes1, extradata2, iExtraDataBytes2);
|
|
||||||
#if LOG_QUEUE_INFO
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
|
||||||
fprintf(fp, "EnQueue2: iRet=%ld\n%s\n\n", iRet, strBuf2);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int64_t __attribute__((visibility("default"))) DeDataQueue(void* pQueue, void** e)
|
|
||||||
{
|
|
||||||
int64_t iRet = 0;
|
|
||||||
|
|
||||||
if (pQueue)
|
|
||||||
{
|
|
||||||
#if LOG_QUEUE_INFO
|
|
||||||
char strBuf[500];
|
|
||||||
char strBuf2[500];
|
|
||||||
FILE* fp = NULL;
|
|
||||||
|
|
||||||
snprintf(strBuf, sizeof(strBuf), "queue%p.log", pQueue);
|
|
||||||
fp = fopen(strBuf, "a+");
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
|
||||||
fprintf(fp, "DeQueue1: %s\n", strBuf2);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
iRet = ((DataQueue*)pQueue)->DeQueue(e);
|
|
||||||
|
|
||||||
#if LOG_QUEUE_INFO
|
|
||||||
if (fp)
|
|
||||||
{
|
|
||||||
((DataQueue*)pQueue)->OutPutStatus(strBuf2, sizeof(strBuf2));
|
|
||||||
fprintf(fp, "DeQueue2: iRet=%ld\n%s\n\n", iRet, strBuf2);
|
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return iRet;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" bool __attribute__((visibility("default"))) DataQueueIsFull(void* pQueue)
|
|
||||||
{
|
|
||||||
return ((DataQueue*)pQueue)->IsFull();
|
|
||||||
}
|
|
||||||
extern "C" void __attribute__((visibility("default"))) ResetDataQueue(void* pQueue)
|
|
||||||
{//delete all data in the queue, and reset all counters to 0
|
|
||||||
((DataQueue*)pQueue)->ResetDataQueue();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" void __attribute__((visibility("default"))) CloseDataQueue(void*& pQueue)
|
|
||||||
{
|
|
||||||
if (pQueue)
|
|
||||||
delete (DataQueue*)pQueue;
|
|
||||||
pQueue = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,78 +0,0 @@
|
||||||
//#pragma once
|
|
||||||
#ifndef __HIT_DATAQUEUE_H
|
|
||||||
#define __HIT_DATAQUEUE_H
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#define MAX_BLOCK_BYTES (1024*1024*2)
|
|
||||||
#define QUEUE_IS_FULL (-1)
|
|
||||||
#define EMPTY_QUEUE_NO_DATA (0)
|
|
||||||
|
|
||||||
class DataQueue
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
DataQueue(int64_t iSizeInKB = 0, int64_t iMaxBlockSize = MAX_BLOCK_BYTES, bool bUseMutex = true, int iReadThreadCnt=1);
|
|
||||||
~DataQueue();
|
|
||||||
|
|
||||||
//private:
|
|
||||||
void* m_pDataBuf; //[DATA_BUF_LEN]
|
|
||||||
int64_t m_iBufOutPos;
|
|
||||||
int64_t m_iBufInPos;
|
|
||||||
int64_t m_iFreeBytes;
|
|
||||||
int64_t m_iQueueBufBytes;
|
|
||||||
int64_t m_iRcvBlocks;//total count
|
|
||||||
int64_t m_iRcvBytes;//total Bytes
|
|
||||||
int64_t m_iProcBlocks;
|
|
||||||
int64_t m_iPaddingBlocks;//padding block cnt in enqueue
|
|
||||||
int64_t m_iProcPaddingBlocks;//processed padding block cnt in dequeue
|
|
||||||
|
|
||||||
int64_t m_iMaxBlockByte;
|
|
||||||
int64_t m_iReservedBufBytes;
|
|
||||||
int64_t m_iReservedBlockNum;
|
|
||||||
int64_t m_iEmptyTimes;
|
|
||||||
int64_t m_iFullTimes;
|
|
||||||
bool m_bUseMutex;
|
|
||||||
pthread_mutex_t m_BufMutex;//pthread_mutex_init(&m_BufMutex, NULL);
|
|
||||||
|
|
||||||
bool IsEmpty(); //
|
|
||||||
bool IsFull();
|
|
||||||
inline bool CanRcv(int iNeedBytes);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
int64_t EnQueue(void* pdata, int64_t iDataBytes = 0, void* extradata = NULL, int64_t iExtraDataBytes = 0, void* extradata2 = NULL, int64_t iExtraDataBytes2 = 0);
|
|
||||||
int64_t DeQueue(void** pdata);//return value: Bytes, >0 if sucess, =0 no data, < 0 error. No data copy, only return the pointer of data area
|
|
||||||
|
|
||||||
uint64_t GetBlockCnt() {
|
|
||||||
return m_iRcvBlocks - m_iProcBlocks;
|
|
||||||
};
|
|
||||||
int64_t GetProcBlockCnt() {
|
|
||||||
return m_iProcBlocks;
|
|
||||||
};
|
|
||||||
int64_t GetTotalRcvBlockCnt() {
|
|
||||||
return m_iRcvBlocks;
|
|
||||||
};
|
|
||||||
int64_t GetFreeBytes();
|
|
||||||
int64_t GetBufBytes();
|
|
||||||
inline int64_t GetQueueFreeBytes();
|
|
||||||
|
|
||||||
|
|
||||||
int InitQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockKB = MAX_BLOCK_BYTES, int iReadThreadCnt = 1);//KB
|
|
||||||
bool CheckQueue(int iLineNo, int iNeedBytes);
|
|
||||||
void OutPutStatus(char* strBuf, int iLen);
|
|
||||||
void ResetDataQueue();
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LOG_QUEUE_INFO 0
|
|
||||||
typedef void* voidPtr;
|
|
||||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenDataQueue(int64_t iTotalKB4QueueBuf, int iMaxBlockBytes, int iReadThreadCnt);
|
|
||||||
extern "C" bool __attribute__((visibility("default"))) GetDataQueueInfo(void* pQueue, int64_t iSize[5]);
|
|
||||||
extern "C" int64_t __attribute__((visibility("default"))) EnDataQueue(void* pQueue, void* e, int64_t iDataBytes, void* extradata1, int64_t iExtraDataBytes1, void* extradata2, int64_t iExtraDataBytes2);
|
|
||||||
extern "C" int64_t __attribute__((visibility("default"))) DeDataQueue(void* pQueue, void** e);
|
|
||||||
extern "C" bool __attribute__((visibility("default"))) DataQueueIsFull(void* pQueue);
|
|
||||||
extern "C" void __attribute__((visibility("default"))) ResetDataQueue(void* pQueue);
|
|
||||||
extern "C" void __attribute__((visibility("default"))) CloseDataQueue(void*& pQueue);
|
|
||||||
#endif
|
|
|
@ -1,42 +0,0 @@
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
namespace QUEUE_LOG_COFIG
|
|
||||||
{
|
|
||||||
void* WriteLogThread(void* param)
|
|
||||||
{
|
|
||||||
CLogFile* pLog = (CLogFile*)(param);
|
|
||||||
pLog->writeQueue2File();//
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
using namespace QUEUE_LOG_COFIG;
|
|
||||||
typedef void* voidPtr;
|
|
||||||
//--------------------------------------------------------------------------------------------------------------
|
|
||||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenLogFile(const char* strPath, const char* strFileName, bool bLogByDay)
|
|
||||||
{
|
|
||||||
//CLogFile* p = new CLogFile(strPath, strFileName, bLogByDay, 1);//use queue
|
|
||||||
CLogFile* p = new CLogFile(strPath, strFileName, false, 1);//use queue 2021.11.09
|
|
||||||
return (voidPtr)p;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------------
|
|
||||||
extern "C" int __attribute__((visibility("default"))) WriteLog(void* pLogFile, const char* fmt, ...)
|
|
||||||
{
|
|
||||||
if (!pLogFile)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
char strInfo[INFO_BUF_LEN];
|
|
||||||
va_list arglist;
|
|
||||||
va_start(arglist, fmt);
|
|
||||||
vsprintf(strInfo, fmt, arglist);
|
|
||||||
va_end(arglist);
|
|
||||||
((CLogFile*)pLogFile)->append_one_item(0, strInfo);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------------------------------------------
|
|
||||||
extern "C" void __attribute__((visibility("default"))) CloseLog(void* pLogFile)
|
|
||||||
{
|
|
||||||
((CLogFile*)pLogFile)->close_log_file();
|
|
||||||
return;
|
|
||||||
}
|
|
|
@ -1,287 +0,0 @@
|
||||||
#ifndef __HIT_LOG_HEADER
|
|
||||||
#define __HIT_LOG_HEADER
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include "dataqueue.h"
|
|
||||||
#define INFO_BUF_LEN 4096//2048
|
|
||||||
|
|
||||||
typedef void* voidPtr;
|
|
||||||
extern "C" voidPtr __attribute__((visibility("default"))) OpenLogFile(const char* strPath, const char* strFileName, bool bLogByDay);
|
|
||||||
//-----------------------------------------------------------------------------------------------------------------
|
|
||||||
extern "C" int __attribute__((visibility("default"))) WriteLog(void* pLogFile, const char* fmt, ...);
|
|
||||||
//-----------------------------------------------------------------------------------------------------------------
|
|
||||||
extern "C" void __attribute__((visibility("default"))) CloseLog(void* pLogFile);
|
|
||||||
|
|
||||||
namespace QUEUE_LOG_COFIG
|
|
||||||
{
|
|
||||||
static uint64_t g_iLogFileMaxSize = 2L * 1024 * 1024 * 1024;
|
|
||||||
static uint64_t g_iCheckLogInterval = 20;//20s
|
|
||||||
|
|
||||||
inline int checkdir(const char* sPathName)
|
|
||||||
{
|
|
||||||
char DirName[256];
|
|
||||||
strcpy(DirName, sPathName);
|
|
||||||
int i, len = strlen(DirName);
|
|
||||||
if (DirName[len - 1] != '/')
|
|
||||||
strcat(DirName, "/");
|
|
||||||
|
|
||||||
len = strlen(DirName);
|
|
||||||
|
|
||||||
for (i = 1; i < len; i++)
|
|
||||||
{
|
|
||||||
if (DirName[i] == '/')
|
|
||||||
{
|
|
||||||
DirName[i] = 0;
|
|
||||||
if (access(DirName, 0) != 0)
|
|
||||||
{
|
|
||||||
if (mkdir(DirName, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) == -1)
|
|
||||||
{
|
|
||||||
perror(" mkdir error");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DirName[i] = '/';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
** log class, it is not thread safe.
|
|
||||||
*/
|
|
||||||
void* WriteLogThread(void* param);
|
|
||||||
|
|
||||||
struct InfoItem
|
|
||||||
{
|
|
||||||
struct tm t;
|
|
||||||
bool bLogTime;
|
|
||||||
char strInfo[INFO_BUF_LEN];
|
|
||||||
int GetLen() { return (uint64_t)(&strInfo[0]) - (uint64_t)(this) + strlen(strInfo) + 1; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class CLogFile
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
char* log_filename;
|
|
||||||
char* log_dirpath;
|
|
||||||
char* log_fullpath_filename;
|
|
||||||
int m_bRecordByDay;
|
|
||||||
int current_day;
|
|
||||||
FILE* file_handle;
|
|
||||||
DataQueue m_InfoQueue; //
|
|
||||||
bool m_bExit;
|
|
||||||
bool m_bUseQueue;
|
|
||||||
bool m_bWriteFinish;
|
|
||||||
pthread_t m_pWriteThreadHandle;
|
|
||||||
private:
|
|
||||||
void set_log_fullpath_filename(struct tm* t)
|
|
||||||
{
|
|
||||||
if (log_fullpath_filename == NULL)
|
|
||||||
log_fullpath_filename = (char*)calloc(strlen(log_dirpath) + 1 + 8 + 1 + strlen(log_filename) + 1 + 10, sizeof(char));
|
|
||||||
if (m_bRecordByDay)
|
|
||||||
{
|
|
||||||
current_day = t->tm_mday;
|
|
||||||
sprintf(log_fullpath_filename, "%s%02d%02d%02d/", log_dirpath, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sprintf(log_fullpath_filename, "%s", log_dirpath);
|
|
||||||
|
|
||||||
checkdir(log_fullpath_filename);
|
|
||||||
strcat(log_fullpath_filename, log_filename);
|
|
||||||
}
|
|
||||||
void open_log_file()
|
|
||||||
{
|
|
||||||
file_handle = fopen(log_fullpath_filename, "a");
|
|
||||||
if (file_handle == NULL)
|
|
||||||
{//2019.07.18------------------
|
|
||||||
fprintf(stderr, "\n----------------------------------------------------------------\n");
|
|
||||||
fprintf(stderr, "***Fatal error: can't open file: %s", log_fullpath_filename);
|
|
||||||
fprintf(stderr, "----------------------------------------------------------------\n");
|
|
||||||
fflush(stderr);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct tm* get_time()
|
|
||||||
{
|
|
||||||
time_t clock;
|
|
||||||
time(&clock);
|
|
||||||
struct tm* t = localtime(&clock);
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
void print_time()
|
|
||||||
{
|
|
||||||
struct tm* t = get_time();
|
|
||||||
fprintf(file_handle, "%4d-%02d-%02d %02d:%02d:%02d\n",
|
|
||||||
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
FILE* GetFileHande() { return file_handle; }
|
|
||||||
CLogFile(const char* dir, const char* name, int byDay, bool bUseQueue = false)
|
|
||||||
{
|
|
||||||
m_bRecordByDay = byDay;
|
|
||||||
m_bUseQueue = bUseQueue;
|
|
||||||
file_handle = NULL;
|
|
||||||
m_bWriteFinish = true;
|
|
||||||
m_bExit = false;
|
|
||||||
|
|
||||||
log_dirpath = (char*)calloc(strlen(dir) + 10, sizeof(char));
|
|
||||||
log_filename = (char*)calloc(strlen(name) + 10, sizeof(char));
|
|
||||||
|
|
||||||
strcpy(log_dirpath, dir);
|
|
||||||
int i, len = strlen(log_dirpath);
|
|
||||||
if (log_dirpath[len - 1] != '/')
|
|
||||||
strcat(log_dirpath, "/");
|
|
||||||
|
|
||||||
strcpy(log_filename, name);
|
|
||||||
log_fullpath_filename = NULL;
|
|
||||||
struct tm* t = get_time();
|
|
||||||
set_log_fullpath_filename(t);
|
|
||||||
|
|
||||||
open_log_file();
|
|
||||||
if (bUseQueue)
|
|
||||||
{
|
|
||||||
m_InfoQueue.InitQueue(32 * 1024, 8 * 2048);
|
|
||||||
pthread_create(&m_pWriteThreadHandle, NULL, WriteLogThread, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~CLogFile()
|
|
||||||
{
|
|
||||||
m_bExit = true;
|
|
||||||
pthread_join(m_pWriteThreadHandle, NULL);
|
|
||||||
close_log_file();
|
|
||||||
free(log_filename);
|
|
||||||
free(log_dirpath);
|
|
||||||
free(log_fullpath_filename);
|
|
||||||
}
|
|
||||||
void append_one_item(int print_time_flag, const char* fmt, ...)
|
|
||||||
{//append the new info into the queue
|
|
||||||
char fmtbuf[INFO_BUF_LEN];
|
|
||||||
va_list arglist;
|
|
||||||
if (m_bExit) return;
|
|
||||||
|
|
||||||
InfoItem tmpInfoItem;
|
|
||||||
|
|
||||||
va_start(arglist, fmt);
|
|
||||||
vsprintf(fmtbuf, fmt, arglist);
|
|
||||||
va_end(arglist);
|
|
||||||
|
|
||||||
snprintf(tmpInfoItem.strInfo, sizeof(tmpInfoItem.strInfo), fmtbuf);
|
|
||||||
tmpInfoItem.t = *get_time();
|
|
||||||
tmpInfoItem.bLogTime = print_time_flag;
|
|
||||||
|
|
||||||
if (m_bUseQueue)
|
|
||||||
m_InfoQueue.EnQueue((void*)(&tmpInfoItem), tmpInfoItem.GetLen());
|
|
||||||
else
|
|
||||||
{
|
|
||||||
writeItem2File(&tmpInfoItem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void checksize(uint64_t iSize)
|
|
||||||
{
|
|
||||||
uint64_t iFileBytes = ftell(file_handle);
|
|
||||||
|
|
||||||
if (iFileBytes > iSize)
|
|
||||||
{
|
|
||||||
char strBackupName[500];
|
|
||||||
char strCurTime[20];
|
|
||||||
time_t tt;
|
|
||||||
tt = time(NULL);
|
|
||||||
strftime(strCurTime, sizeof(strCurTime), "%Y.%m.%d-%H.%M.%S", localtime(&tt));//产生“YYYY-MM-DD hh:mm:ss”格式的字符串。
|
|
||||||
sprintf(strBackupName, "%s-bak%s", log_fullpath_filename, strCurTime);
|
|
||||||
|
|
||||||
close_log_file();
|
|
||||||
rename(log_fullpath_filename, strBackupName);//把原文件重命名为新的文件名
|
|
||||||
open_log_file();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void writeItem2File(InfoItem* pInfoItem)
|
|
||||||
{
|
|
||||||
if (file_handle == NULL)
|
|
||||||
{//2019.07.18
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int iBytes;
|
|
||||||
if ((m_bRecordByDay) && (pInfoItem->t.tm_mday != current_day))
|
|
||||||
{//change_to_new_day
|
|
||||||
close_log_file();
|
|
||||||
current_day = pInfoItem->t.tm_mday;
|
|
||||||
set_log_fullpath_filename(&(pInfoItem->t));
|
|
||||||
open_log_file();
|
|
||||||
char strCmd[300];
|
|
||||||
sprintf(strCmd, "find %s -type d -mtime +30 -exec rm -rf {} \\;", log_dirpath);
|
|
||||||
system(strCmd);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pInfoItem->bLogTime)
|
|
||||||
{
|
|
||||||
iBytes = fprintf(file_handle, "%s %4d.%02d.%02d %02d:%02d:%02d\n",
|
|
||||||
pInfoItem->strInfo,
|
|
||||||
pInfoItem->t.tm_year + 1900, pInfoItem->t.tm_mon + 1, pInfoItem->t.tm_mday,
|
|
||||||
pInfoItem->t.tm_hour, pInfoItem->t.tm_min, pInfoItem->t.tm_sec);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
iBytes = fprintf(file_handle, "%s", pInfoItem->strInfo);
|
|
||||||
|
|
||||||
if (iBytes < 0)
|
|
||||||
fprintf(stderr, "***writing \"%s\" to log failed! errno:%d, %s\n", pInfoItem->strInfo, errno, strerror(errno));
|
|
||||||
else
|
|
||||||
fflush(file_handle);
|
|
||||||
}
|
|
||||||
void writeQueue2File()
|
|
||||||
{
|
|
||||||
unsigned int iWiteItems = 0;
|
|
||||||
InfoItem* pInfoItem;
|
|
||||||
struct tm* t;
|
|
||||||
m_bWriteFinish = false;
|
|
||||||
unsigned n = 0;
|
|
||||||
int iBytes;
|
|
||||||
while (!m_bExit)
|
|
||||||
{
|
|
||||||
iBytes = m_InfoQueue.DeQueue((void**)(&pInfoItem));
|
|
||||||
if (iBytes <= 0)
|
|
||||||
{
|
|
||||||
sleep(1);//10ms
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
writeItem2File(pInfoItem);
|
|
||||||
if ((++n % g_iCheckLogInterval == 0) && (!m_bRecordByDay))
|
|
||||||
checksize(g_iLogFileMaxSize);// 2L * 1024 * 1024 * 1024);//不超过2GB
|
|
||||||
}
|
|
||||||
t = get_time();
|
|
||||||
fprintf(file_handle, "...finish and exit! @%4d.%02d.%02d %02d:%02d:%02d\n\n",
|
|
||||||
t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
|
||||||
fflush(file_handle);
|
|
||||||
m_bWriteFinish = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void close_log_file()
|
|
||||||
{
|
|
||||||
if (file_handle != NULL)
|
|
||||||
{
|
|
||||||
fflush(file_handle);
|
|
||||||
fclose(file_handle);
|
|
||||||
file_handle = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_expired_logs()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
//void * WriteLogThread(void* param)
|
|
||||||
//{
|
|
||||||
// CLogFile *pLog = (CLogFile*)(param);
|
|
||||||
// pLog->writeQueue2File();//
|
|
||||||
//}
|
|
||||||
//---------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,17 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
if echo "$@" | grep -iq r; then
|
|
||||||
Param1="RELEASE_VERSION=yes"
|
|
||||||
else
|
|
||||||
Param1="DEBUG_VERSION=yes"
|
|
||||||
fi
|
|
||||||
|
|
||||||
make clean
|
|
||||||
clear
|
|
||||||
if echo "$@" | grep -iq e; then
|
|
||||||
#------ compile for euler -------------------
|
|
||||||
make -j 4 $Param1 CXX=arm-ztkp_openeuler-linux-gnueabi-g++ AR=arm-ztkp_openeuler-linux-gnueabi-ar OUTPUT_LIB_DIR=../../libs-euler/
|
|
||||||
else
|
|
||||||
#------- compile for arm32 ------------------
|
|
||||||
make -j 4 $Param1 CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar OUTPUT_LIB_DIR=../../libs-arm32/
|
|
||||||
fi
|
|
||||||
|
|
2
mak
2
mak
|
@ -19,5 +19,5 @@ fi
|
||||||
|
|
||||||
mkdir -p ${BUILD_PREFIX} && cd ${BUILD_PREFIX}
|
mkdir -p ${BUILD_PREFIX} && cd ${BUILD_PREFIX}
|
||||||
rm -f CMakeCache.txt
|
rm -f CMakeCache.txt
|
||||||
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=../../bin/${BUILD_PREFIX} ../..
|
cmake -DCMAKE_BUILD_TYPE=${BUILD_TYPE} -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN} -DEXECUTABLE_OUTPUT_PATH=../../bin/${BUILD_PREFIX} -DLIBRARY_OUTPUT_PATH=../../lib/${BUILD_PREFIX} ../..
|
||||||
cmake --build . -j 4 --
|
cmake --build . -j 4 --
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
mkdir -p dist
|
||||||
|
|
||||||
|
zip -r "dist/exint-build-$(date +%Y%m%d-%H%M%S).zip" bin/ lib/ config/\
|
||||||
|
scripts/ README.md
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/bin/sh
|
||||||
|
mkdir -p dist
|
||||||
|
|
||||||
|
tar -czvf "dist/exint-$(date +%Y%m%d-%H%M%S).tar.gz" src/ include/ tests/ config/\
|
||||||
|
scripts/ toolchains/ tools/ README.md CMakeLists.txt mak .gitignore
|
|
@ -389,7 +389,7 @@ if __name__ == "__main__":
|
||||||
for p in namespace.path:
|
for p in namespace.path:
|
||||||
if '*' in p:
|
if '*' in p:
|
||||||
paths.extend(glob(p, recursive=True))
|
paths.extend(glob(p, recursive=True))
|
||||||
else:
|
elif os.path.isfile(p):
|
||||||
paths.append(p)
|
paths.append(p)
|
||||||
for p in paths:
|
for p in paths:
|
||||||
f = CTestCaseFile(p)
|
f = CTestCaseFile(p)
|
||||||
|
|
|
@ -60,9 +60,8 @@ int exint_init_from_tty(int host_com_tty, int telemetry_com_tty, et_callback_t c
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exint_send(uint32_t type, size_t len, union PacketData data) {
|
void exint_send(uint32_t type, size_t len, void* data) {
|
||||||
const char* event_name;
|
const char* event_name;
|
||||||
void* data_pointer = data.pd_pointer;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ET_TYPE_COMMAND:
|
case ET_TYPE_COMMAND:
|
||||||
event_name = "send_command";
|
event_name = "send_command";
|
||||||
|
@ -73,7 +72,7 @@ void exint_send(uint32_t type, size_t len, union PacketData data) {
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exint_event(event_name, len, data_pointer);
|
exint_event(event_name, len, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exint_finialize() {
|
void exint_finialize() {
|
||||||
|
@ -83,6 +82,6 @@ void exint_finialize() {
|
||||||
pthread_cancel(telemetry_thread);
|
pthread_cancel(telemetry_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void exint_handle_pack(uint32_t type, size_t len, union PacketData data) {
|
void exint_handle_pack(uint32_t type, size_t len, void* data) {
|
||||||
et_callback(type, len, data);
|
et_callback(type, len, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ volatile bool g_bNeedReboot = false;
|
||||||
volatile int32_t g_iMS2Reboot = 1000;
|
volatile int32_t g_iMS2Reboot = 1000;
|
||||||
|
|
||||||
void get_telemetry_data(TelemetryRequestData* data) {
|
void get_telemetry_data(TelemetryRequestData* data) {
|
||||||
exint_handle_pack(ET_TYPE_TELEMETRY_REQUEST, sizeof(TelemetryRequestData), { .pd_pointer = data });
|
exint_handle_pack(ET_TYPE_TELEMETRY_REQUEST, sizeof(TelemetryRequestData), data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a msg data for upper host telemetry*/
|
/* create a msg data for upper host telemetry*/
|
||||||
|
@ -438,7 +438,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
||||||
else
|
else
|
||||||
//-------END 2024.10.23 noted by zgb
|
//-------END 2024.10.23 noted by zgb
|
||||||
*/
|
*/
|
||||||
exint_handle_pack(ET_TYPE_COMMAND, 6, {.pd_pointer = frame->payload});
|
exint_handle_pack(ET_TYPE_COMMAND, 6, frame->payload);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case COM_FRAME_TYPE_SPEECH_INJECTED:
|
case COM_FRAME_TYPE_SPEECH_INJECTED:
|
||||||
|
@ -454,7 +454,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
||||||
COM_FRAME_ADDRESS_VOIX,
|
COM_FRAME_ADDRESS_VOIX,
|
||||||
COM_FRAME_TYPE_SPEECH_INJECTED,
|
COM_FRAME_TYPE_SPEECH_INJECTED,
|
||||||
payload, 6, true);
|
payload, 6, true);
|
||||||
exint_handle_pack(ET_TYPE_TEXT, 6, {.pd_pointer = f_data->payload});
|
exint_handle_pack(ET_TYPE_TEXT, 6, f_data->payload);
|
||||||
if (ComFrame_Send(tty_id, f_data, true)) {
|
if (ComFrame_Send(tty_id, f_data, true)) {
|
||||||
PrintFilePos(); fprintf(stderr, "send telemetry data frame error: %s\n", strerror(errno));
|
PrintFilePos(); fprintf(stderr, "send telemetry data frame error: %s\n", strerror(errno));
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
||||||
PrintFilePos(); fprintf(stderr, " com frame interval %d\n", iIntervalTime);
|
PrintFilePos(); fprintf(stderr, " com frame interval %d\n", iIntervalTime);
|
||||||
tLastTime = tCurTime;
|
tLastTime = tCurTime;
|
||||||
|
|
||||||
exint_handle_pack(ET_TYPE_AUDIO, ComFrame_PAYLOAD_LENGTH(frame), {.pd_pointer = frame->payload});
|
exint_handle_pack(ET_TYPE_AUDIO, ComFrame_PAYLOAD_LENGTH(frame), frame->payload);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -550,7 +550,7 @@ void* upper_host_com_thread(void* arg) {//hand-control display processing unit
|
||||||
if(!alarm)
|
if(!alarm)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
exint_handle_pack(ET_TYPE_TEXT, sizeof(alarm), {.pd_pointer = alarm});
|
exint_handle_pack(ET_TYPE_TEXT, sizeof(alarm), alarm);
|
||||||
|
|
||||||
uint8_t payload[6] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
|
uint8_t payload[6] = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55};
|
||||||
ComFrame* f_data = ComFrame_New(
|
ComFrame* f_data = ComFrame_New(
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <atomic>
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
#include "c_testcase.h"
|
#include "c_testcase.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#define TEST_CASE_STATUS_PASSED 0
|
#define TEST_CASE_STATUS_PASSED 0
|
||||||
|
@ -20,6 +24,8 @@ using namespace std;
|
||||||
|
|
||||||
#define MAX_TESTCASE 64
|
#define MAX_TESTCASE 64
|
||||||
|
|
||||||
|
#define DEFAULT_TTY_COL_SIZE 80
|
||||||
|
|
||||||
struct TestCase {
|
struct TestCase {
|
||||||
const char* name;
|
const char* name;
|
||||||
test_case func;
|
test_case func;
|
||||||
|
@ -34,6 +40,7 @@ static context_func teardown = NULL;
|
||||||
|
|
||||||
static atomic_bool testcase_running;
|
static atomic_bool testcase_running;
|
||||||
static jmp_buf testcase_env;
|
static jmp_buf testcase_env;
|
||||||
|
static std::thread::id testcase_thread_id;
|
||||||
static int testcase_exit_code = 0;
|
static int testcase_exit_code = 0;
|
||||||
|
|
||||||
int _add_test_case(const char* name, test_case func) {
|
int _add_test_case(const char* name, test_case func) {
|
||||||
|
@ -62,18 +69,36 @@ int _set_teardown(context_func func) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void __attribute__((noreturn)) test_case_abort(int exit_code) {
|
[[noreturn]] void test_case_abort(int exit_code) {
|
||||||
if (!testcase_running.load(std::memory_order_acquire)) {
|
auto tid = std::this_thread::get_id();
|
||||||
|
if (!testcase_running.load(std::memory_order_acquire) || tid != testcase_thread_id) {
|
||||||
exit(exit_code);
|
exit(exit_code);
|
||||||
}
|
}
|
||||||
testcase_exit_code = exit_code;
|
testcase_exit_code = exit_code;
|
||||||
longjmp(testcase_env, 1);
|
longjmp(testcase_env, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline int get_tty_col(int fd) {
|
static inline int get_tty_col(int fd) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
// Windows
|
||||||
|
HANDLE hConsole = (HANDLE)_get_osfhandle(fd);
|
||||||
|
if (hConsole == INVALID_HANDLE_VALUE) {
|
||||||
|
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||||
|
}
|
||||||
|
|
||||||
|
CONSOLE_SCREEN_BUFFER_INFO csbi;
|
||||||
|
if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) {
|
||||||
|
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||||
|
}
|
||||||
|
return csbi.srWindow.Right - csbi.srWindow.Left + 1; // 计算列数
|
||||||
|
#else
|
||||||
|
// POSIX (Linux, macOS, etc.)
|
||||||
struct winsize size;
|
struct winsize size;
|
||||||
ioctl(fd, TIOCGWINSZ,&size);
|
if (ioctl(fd, TIOCGWINSZ, &size) == -1) {
|
||||||
return size.ws_col;
|
return DEFAULT_TTY_COL_SIZE; // 错误处理
|
||||||
|
}
|
||||||
|
return size.ws_col; // 返回列数
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void print_separator(char lc) {
|
static __inline void print_separator(char lc) {
|
||||||
|
@ -140,6 +165,7 @@ static int run_test_case_func(test_case func) {
|
||||||
if (setjmp(testcase_env)) {
|
if (setjmp(testcase_env)) {
|
||||||
return testcase_exit_code;
|
return testcase_exit_code;
|
||||||
}
|
}
|
||||||
|
testcase_thread_id = std::this_thread::get_id();
|
||||||
int ret = func();
|
int ret = func();
|
||||||
running = true;
|
running = true;
|
||||||
if (!testcase_running.compare_exchange_strong(running, false, std::memory_order_acq_rel)) {
|
if (!testcase_running.compare_exchange_strong(running, false, std::memory_order_acq_rel)) {
|
||||||
|
|
|
@ -9,16 +9,16 @@
|
||||||
#include "c_testcase.h"
|
#include "c_testcase.h"
|
||||||
|
|
||||||
static int g_telemetry_request_count = 0;
|
static int g_telemetry_request_count = 0;
|
||||||
static DataQueue<std::tuple<uint32_t, size_t, PacketData>> g_data_queue;
|
static DataQueue<std::tuple<uint32_t, size_t, void*>> g_data_queue;
|
||||||
static int host_com_master_id;
|
static int host_com_master_id;
|
||||||
static int telemetry_com_master_id;
|
static int telemetry_com_master_id;
|
||||||
|
|
||||||
void exint_data_callback(uint32_t type, size_t size, PacketData data) {
|
void exint_data_callback(uint32_t type, size_t size, void* data) {
|
||||||
if (type == ET_TYPE_TELEMETRY_REQUEST) {
|
if (type == ET_TYPE_TELEMETRY_REQUEST) {
|
||||||
g_telemetry_request_count++;
|
g_telemetry_request_count++;
|
||||||
memset(data.pd_pointer, 0, size);
|
memset(data, 0, size);
|
||||||
((TelemetryRequestData*)data.pd_pointer)->app_ver_high = 1;
|
((TelemetryRequestData*)data)->app_ver_high = 1;
|
||||||
((TelemetryRequestData*)data.pd_pointer)->app_ver_low = 2;
|
((TelemetryRequestData*)data)->app_ver_low = 2;
|
||||||
} else {
|
} else {
|
||||||
g_data_queue.Push(std::make_tuple(type, size, data));
|
g_data_queue.Push(std::make_tuple(type, size, data));
|
||||||
}
|
}
|
||||||
|
@ -80,6 +80,21 @@ TEST_CASE(test_host_telemetry) {
|
||||||
END_TEST;
|
END_TEST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_CASE(test_callback) {
|
||||||
|
uint8_t command[] = { 0x00, 0x01, 0x02, 0x03, 0xAA, 0xAA};
|
||||||
|
auto command_msg = ComFrame_New(COM_FRAME_ADDRESS_VOIX, COM_FRAME_TYPE_COMMAND, command, sizeof(command), true);
|
||||||
|
assert(!ComFrame_Send(host_com_master_id, command_msg, true));
|
||||||
|
|
||||||
|
uint32_t tp;
|
||||||
|
size_t len;
|
||||||
|
void* pack;
|
||||||
|
std::tie(tp, len, pack) = g_data_queue.Pop(std::chrono::milliseconds(1000));
|
||||||
|
assert_eq(tp, ET_TYPE_COMMAND);
|
||||||
|
assert_eq(len, sizeof(command));
|
||||||
|
assert_mem_eq(command, pack, len);
|
||||||
|
END_TEST;
|
||||||
|
}
|
||||||
|
|
||||||
TEST_CASE(test_send_command) {
|
TEST_CASE(test_send_command) {
|
||||||
ComFrame* command_frame = NULL;
|
ComFrame* command_frame = NULL;
|
||||||
bool timeout_flag = true;
|
bool timeout_flag = true;
|
||||||
|
@ -89,8 +104,9 @@ TEST_CASE(test_send_command) {
|
||||||
command_frame = ComFrame_ReceiveEx(host_com_master_id, NULL, 100, &offset, &cached_size, &timeout_flag, true);
|
command_frame = ComFrame_ReceiveEx(host_com_master_id, NULL, 100, &offset, &cached_size, &timeout_flag, true);
|
||||||
}).detach();
|
}).detach();
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
char command_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
|
char command_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
|
||||||
exint_send(ET_TYPE_COMMAND, 6, { .pd_pointer = command_data });
|
exint_send(ET_TYPE_COMMAND, 6, command_data );
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 100; i++) {
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
|
@ -102,7 +118,6 @@ TEST_CASE(test_send_command) {
|
||||||
assert(command_frame);
|
assert(command_frame);
|
||||||
assert_eq(ComFrame_TYPE(command_frame), COM_FRAME_TYPE_REQUEST);
|
assert_eq(ComFrame_TYPE(command_frame), COM_FRAME_TYPE_REQUEST);
|
||||||
assert_eq(ComFrame_PAYLOAD_LENGTH(command_frame), 6);
|
assert_eq(ComFrame_PAYLOAD_LENGTH(command_frame), 6);
|
||||||
assert_eq(ComFrame_PAYLOAD(command_frame)[0], 0x00);
|
assert_mem_eq(ComFrame_PAYLOAD(command_frame), command_data, 6);
|
||||||
assert_eq(ComFrame_PAYLOAD(command_frame)[5], 0x05);
|
|
||||||
END_TEST;
|
END_TEST;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ TEST_CASE(test_clear) {
|
||||||
}
|
}
|
||||||
throw std::runtime_error("QueueException not thrown");
|
throw std::runtime_error("QueueException not thrown");
|
||||||
});
|
});
|
||||||
usleep(100);
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
q.Clear();
|
q.Clear();
|
||||||
t.join();
|
t.join();
|
||||||
END_TEST;
|
END_TEST;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
set(CMAKE_SYSTEM_NAME Linux)
|
set(CMAKE_SYSTEM_NAME Linux)
|
||||||
set(CMAKE_SYSTEM_PROCESSOR arm)
|
set(CMAKE_SYSTEM_PROCESSOR arm)
|
||||||
|
|
||||||
set(CMAKE_C_COMPILER arm-none-linux-gnueabihf-gcc)
|
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
|
||||||
set(CMAKE_CXX_COMPILER arm-none-linux-gnueabihf-g++)
|
set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g++)
|
||||||
|
|
|
@ -1,203 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 2.8)
|
|
||||||
|
|
||||||
###################################################################################
|
|
||||||
project(libgo)
|
|
||||||
|
|
||||||
enable_language(C ASM)
|
|
||||||
|
|
||||||
if (CMAKE_BUILD_TYPE)
|
|
||||||
else()
|
|
||||||
set(CMAKE_BUILD_TYPE RELEASE)
|
|
||||||
#set(CMAKE_BUILD_TYPE DEBUG)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message("------------ Options -------------")
|
|
||||||
message(" CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}")
|
|
||||||
message(" CMAKE_COMMAND: ${CMAKE_COMMAND}")
|
|
||||||
|
|
||||||
option(ENABLE_DEBUGGER "enable debugger" OFF)
|
|
||||||
if (ENABLE_DEBUGGER)
|
|
||||||
set(ENABLE_DEBUGGER 1)
|
|
||||||
message (" enable_debugger: yes")
|
|
||||||
else()
|
|
||||||
set(ENABLE_DEBUGGER 0)
|
|
||||||
message (" enable_debugger: no")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
option(DISABLE_HOOK "disable hook" OFF)
|
|
||||||
if (DISABLE_HOOK)
|
|
||||||
set(ENABLE_HOOK 0)
|
|
||||||
message (" enable_hook: no")
|
|
||||||
else()
|
|
||||||
set(ENABLE_HOOK 1)
|
|
||||||
message (" enable_hook: yes")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (BUILD_DYNAMIC)
|
|
||||||
message (" build dynamic lib: yes")
|
|
||||||
else()
|
|
||||||
message (" build dynamic lib: no")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message("-------------- Env ---------------")
|
|
||||||
message(" CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
|
|
||||||
message(" CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")
|
|
||||||
message("----------------------------------")
|
|
||||||
|
|
||||||
configure_file(${PROJECT_SOURCE_DIR}/libgo/common/cmake_config.h.in ${PROJECT_SOURCE_DIR}/libgo/common/cmake_config.h)
|
|
||||||
message("----------------------------------")
|
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
set(CMAKE_CXX_FLAGS "-std=c++17 -fPIC -Wall ${CMAKE_CXX_FLAGS}")
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "-g")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -DNDEBUG")
|
|
||||||
|
|
||||||
set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS S)
|
|
||||||
if(CMAKE_CROSSCOMPILING)
|
|
||||||
message(STATUS "> CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
|
|
||||||
set(ASM_DIR "${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/")
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_arm_aapcs_elf_gas.S")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_arm_aapcs_elf_gas.S")
|
|
||||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_arm64_aapcs_elf_gas.S")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_arm64_aapcs_elf_gas.S")
|
|
||||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_x86_64_sysv_elf_gas.S")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_x86_64_sysv_elf_gas.S")
|
|
||||||
endif()
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") # macOS
|
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_arm64_aapcs_macho_gas.S")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_arm64_aapcs_macho_gas.S")
|
|
||||||
endif()
|
|
||||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Windows")
|
|
||||||
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_i386_ms_pe_gas.asm")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_i386_ms_pe_gas.asm")
|
|
||||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
|
|
||||||
set(jump_asm_file "${ASM_DIR}jump_x86_64_ms_pe_gas.asm")
|
|
||||||
set(make_asm_file "${ASM_DIR}make_x86_64_ms_pe_gas.asm")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if (NOT jump_asm_file OR NOT make_asm_file)
|
|
||||||
message(FATAL_ERROR "--> select asm source file failed")
|
|
||||||
return()
|
|
||||||
endif()
|
|
||||||
file(COPY ${jump_asm_file} DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
|
||||||
file(COPY ${make_asm_file} DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
|
||||||
else()
|
|
||||||
message("--> select asm source file, please wait about 5 seconds ...")
|
|
||||||
execute_process(COMMAND "${PROJECT_SOURCE_DIR}/third_party/select_asm.sh" "${PROJECT_SOURCE_DIR}" "jump" OUTPUT_VARIABLE jump_asm_file)
|
|
||||||
execute_process(COMMAND "${PROJECT_SOURCE_DIR}/third_party/select_asm.sh" "${PROJECT_SOURCE_DIR}" "make" OUTPUT_VARIABLE make_asm_file)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# 输出选择的汇编文件路径
|
|
||||||
message(STATUS "Jump ASM File: ${jump_asm_file}")
|
|
||||||
message(STATUS "Make ASM File: ${make_asm_file}")
|
|
||||||
elseif (WIN32)
|
|
||||||
# windows platform
|
|
||||||
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
|
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd /EHsc")
|
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT /EHsc")
|
|
||||||
|
|
||||||
#set(CMAKE_ASM_SOURCE_FILE_EXTENSIONS asm)
|
|
||||||
#file(COPY ${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/make_x86_64_ms_pe_masm.asm DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
|
||||||
#file(COPY ${PROJECT_SOURCE_DIR}/third_party/boost.context/libs/context/src/asm/jump_x86_64_ms_pe_masm.asm DESTINATION ${PROJECT_SOURCE_DIR}/libgo/context)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message("------------ Cxx flags -------------")
|
|
||||||
message(" CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}: ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
|
|
||||||
message("------------------------------------")
|
|
||||||
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR})
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/common CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/context CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/task CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/scheduler CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/sync CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/timer CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/cls CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/defer CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/pool CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/debug CO_SRC_LIST)
|
|
||||||
|
|
||||||
if (NOT DISABLE_HOOK)
|
|
||||||
if (UNIX)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/unix CO_SRC_LIST)
|
|
||||||
elseif (WIN32)
|
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/libgo/netio/windows)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/windows CO_SRC_LIST)
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/context/fiber CO_SRC_LIST)
|
|
||||||
list(APPEND CO_SRC_LIST ${PROJECT_SOURCE_DIR}/libgo/netio/windows/xhook/xhook.cpp)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
aux_source_directory(${PROJECT_SOURCE_DIR}/libgo/netio/disable_hook CO_SRC_LIST)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(TARGET "libgo")
|
|
||||||
set(STATIC_T "libgo_static")
|
|
||||||
set(STATIC_HOOK "static_hook")
|
|
||||||
|
|
||||||
list(APPEND CO_SRC_LIST ${jump_asm_file})
|
|
||||||
list(APPEND CO_SRC_LIST ${make_asm_file})
|
|
||||||
add_library("${STATIC_T}" STATIC ${CO_SRC_LIST})
|
|
||||||
set_target_properties("${STATIC_T}" PROPERTIES OUTPUT_NAME "${TARGET}")
|
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
install(TARGETS ${STATIC_T} LIBRARY DESTINATION "lib" ARCHIVE DESTINATION "lib")
|
|
||||||
install(DIRECTORY ${PROJECT_SOURCE_DIR}/libgo/ DESTINATION "include/libgo" FILES_MATCHING PATTERN "*.h")
|
|
||||||
#PATTERN "windows" EXCLUDE
|
|
||||||
|
|
||||||
add_library("${STATIC_HOOK}" STATIC "${PROJECT_SOURCE_DIR}/libgo/netio/unix/static_hook/static_hook.cpp")
|
|
||||||
|
|
||||||
if (BUILD_DYNAMIC)
|
|
||||||
set(SHARED_T "libgo_dynamic")
|
|
||||||
add_library("${SHARED_T}" SHARED ${CO_SRC_LIST})
|
|
||||||
set_target_properties("${SHARED_T}" PROPERTIES OUTPUT_NAME "${TARGET}")
|
|
||||||
target_link_libraries("${SHARED_T}" ${LINK_LIBS} -ldl)
|
|
||||||
install(TARGETS ${SHARED_T} LIBRARY DESTINATION "lib" ARCHIVE DESTINATION "lib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_custom_target(debug
|
|
||||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=DEBUG ${CMAKE_SOURCE_DIR}
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
||||||
COMMENT "Switch CMAKE_BUILD_TYPE to Debug"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(release
|
|
||||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=RELEASE ${CMAKE_SOURCE_DIR}
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
||||||
COMMENT "Switch CMAKE_BUILD_TYPE to Release"
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PROFILE_FLAGS "-pg ${CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}}")
|
|
||||||
|
|
||||||
#message("PROFILE_FLAGS: ${PROFILE_FLAGS}")
|
|
||||||
add_custom_target(profile
|
|
||||||
COMMAND ${CMAKE_COMMAND} -DCMAKE_BUILD_TYPE=PROFILE -DCMAKE_CXX_FLAGS_PROFILE=\\'${PROFILE_FLAGS}\\' ${CMAKE_SOURCE_DIR}
|
|
||||||
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target all
|
|
||||||
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
|
|
||||||
COMMENT "Switch CMAKE_BUILD_TYPE to PROFILE"
|
|
||||||
)
|
|
||||||
|
|
||||||
add_custom_target(uninstall
|
|
||||||
COMMAND rm ${CMAKE_INSTALL_PREFIX}/lib/liblibgo.a ${CMAKE_INSTALL_PREFIX}/lib/liblibgo.so ${CMAKE_INSTALL_PREFIX}/lib/liblibgo_main.a -f
|
|
||||||
COMMAND rm ${CMAKE_INSTALL_PREFIX}/include/libgo -rf
|
|
||||||
)
|
|
||||||
|
|
||||||
elseif (WIN32)
|
|
||||||
set_target_properties("${STATIC_T}" PROPERTIES COMPILE_FLAGS "/wd4819 /wd4267")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
if (BOOST_ROOT)
|
|
||||||
add_subdirectory(${PROJECT_SOURCE_DIR}/test/gtest_unit)
|
|
||||||
add_subdirectory(${PROJECT_SOURCE_DIR}/tutorial)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
Loading…
Reference in New Issue