#include #include #include #include "common.h" #include // 必须包含此头文件以使用变参宏 static char g_sBuildTime[128] = {0}; WEAK void elog_output(uint8_t level, const char *tag, const char *file, const char *func, long line, const char *format, ...) { #ifdef BUILD_COMMON va_list args; RD_PRINTF("[%u/%s] [%s] (%s:%ld) ", level, tag, func, file, line); va_start(args, format); vprintf(format, args); va_end(args); RD_PRINTF("\r\n"); #else RD_PRINTF("[%u/%s] [%s] (%s:%ld) %s\r\n", level, tag, func, file, line, format); #endif } /** * @brief Rd_String2Array * @note 将字符串按照一定的分割符分割为字符串数组 * @param _pSrc: 输入的字符串 * @param _pRes[]: 输出的字符串数组 * @param _iNum: 字符串的数组元素数 * @param _Ptr: 分割符 * @retval 0成功,非0失败 */ int Rd_String2Array(char *_pSrc, char *_pRes[], int _iNum, char *_Ptr) { int iRet = RD_SUCCESS; char *pcTemp = _pSrc; char *pcStr = NULL; int i = 0; if(NULL == _pSrc || NULL == _pRes || NULL == _Ptr) { goto END; } while (NULL != (pcTemp = strtok_r(pcTemp, _Ptr, &pcStr)) && i < _iNum) { _pRes[i++] = pcTemp; pcTemp = NULL; } END: return iRet; } /** * @brief Rd_Array2String * @note 将字符串数组用一定的连接符拼接成字符串 * @param _pRes: 存放输出的字符串 * @param _iLen: 字符串长度 * @param _pSrc[]: 输入的字符串数组 * @param _iNum: 字符串的数组元素数 * @param _Ptr: 连接符 * @retval 0成功,非0失败 */ int Rd_Array2String(char *_pRes, int _iLen, char *_pSrc[], int _iNum, char *_Ptr) { int iRet = RD_SUCCESS; int i = 0; if(NULL == _pSrc || NULL == _pRes || NULL == _Ptr || _iNum <= 0 || _iLen <= 0) { iRet = RD_INVALUE; goto END; } for (i = 0; i < _iNum; i++) { (void)strncat(_pRes, _pSrc[i], _iLen -1); if(i < _iNum - 1) { (void)strncat(_pRes, _Ptr, _iLen -1); } } END: return iRet; } // 跨平台:判断路径是否存在(文件或目录均可) int Rd_FileExists(const char *_psPath) { if (!_psPath) return 0; struct stat sb; return (stat(_psPath, &sb) == 0); } // 更进一步:仅判断是否为普通文件(排除目录、设备等) int Rd_RegularFileExists(const char *_psPath) { if (!_psPath) return 0; struct stat sb; return (stat(_psPath, &sb) == 0) && S_ISREG(sb.st_mode); } char *Rd_GetBuildTime(void) { #ifdef RD_HOSTNAME snprintf(g_sBuildTime, sizeof(g_sBuildTime), "%s build [%s %s] by %s", RD_VERSION, __DATE__, __TIME__, RD_HOSTNAME); #else snprintf(g_sBuildTime, sizeof(g_sBuildTime), "%s build [%s %s]", RD_VERSION, __DATE__, __TIME__); #endif return g_sBuildTime; } uint16_t Rd_modbusCRC16(const uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; for (uint16_t i = 0; i < length; i++) { crc ^= (uint16_t)data[i]; for (uint8_t j = 0; j < 8; j++) { if ((crc & 0x0001) != 0) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return crc; }