新手入门
- 积分
- 8
- 金钱
- 8
- 注册时间
- 2022-12-29
- 在线时间
- 2 小时
|
本帖最后由 elecrui 于 2023-1-12 17:18 编辑
USMART例程下usmart_str.c文件中usmart_get_fname函数原文件第390-410行(下文代码120行-140行),在接收完函数名后计算参数个数,是通过括号中“,”个数计算的,但这里并未判断是否正在字符串内,如果参数中包含字符串,且字符串中有“,”,可能造成参数个数计算错误。
- /**
- * @brief 从str中得到函数名
- * [url=home.php?mod=space&uid=271674]@param[/url] str : 源字符串指针
- * @param fname : 获取到的函数名字指针
- * @param pnum : 函数的参数个数
- * @param rval : 是否需要显示返回值(0,不需要;1,需要)
- * @retval 0,成功;其他,错误代码.
- */
- uint8_t usmart_get_fname(char *str, char *fname, uint8_t *pnum, uint8_t *rval)
- {
- uint8_t res;
- uint8_t fover = 0; /* 括号深度 */
- char *strtemp;
- uint8_t offset = 0;
- uint8_t parmnum = 0;
- uint8_t temp = 1;
- char fpname[6]; /* void+X+'/0' */
- uint8_t fplcnt = 0; /* 第一个参数的长度计数器 */
- uint8_t pcnt = 0; /* 参数计数器 */
- uint8_t nchar;
- /* 判断函数是否有返回值 */
- strtemp = str;
- while (*strtemp != '\0') /* 没有结束 */
- {
- if (*strtemp != ' ' && (pcnt & 0X7F) < 5) /* 最多记录5个字符 */
- {
- if (pcnt == 0)pcnt |= 0X80; /* 置位最高位,标记开始接收返回值类型 */
- if (((pcnt & 0x7f) == 4) && (*strtemp != '*'))break; /* 最后一个字符,必须是* */
- fpname[pcnt & 0x7f] = *strtemp; /* 记录函数的返回值类型 */
- pcnt++;
- }
- else if (pcnt == 0X85)
- {
- break;
- }
- strtemp++;
- }
- if (pcnt) /* 接收完了 */
- {
- fpname[pcnt & 0x7f] = '\0'; /* 加入结束符 */
- if (usmart_strcmp(fpname, "void") == 0)
- {
- *rval = 0; /* 不需要返回值 */
- }
- else
- {
- *rval = 1; /* 需要返回值 */
- }
- pcnt = 0;
- }
- res = 0;
- strtemp = str;
- while (*strtemp != '(' && *strtemp != '\0') /* 此代码找到函数名的真正起始位置 */
- {
- strtemp++;
- res++;
- if (*strtemp == ' ' || *strtemp == '*')
- {
- nchar = usmart_search_nextc(strtemp); /* 获取下一个字符 */
- if (nchar != '(' && nchar != '*')offset = res; /* 跳过空格和*号 */
- }
- }
- strtemp = str;
- if (offset)strtemp += offset + 1; /* 跳到函数名开始的地方 */
- res = 0;
- nchar = 0; /* 是否正在字符串里面的标志,0,不在字符串;1,在字符串; */
- while (1)
- {
- if (*strtemp == 0)
- {
- res = USMART_FUNCERR; /* 函数错误 */
- break;
- }
- else if (*strtemp == '(' && nchar == 0)
- {
- fover++; /* 括号深度增加一级 */
- }
- else if (*strtemp == ')' && nchar == 0)
- {
- if (fover)
- {
- fover--;
- }
- else
- {
- res = USMART_FUNCERR; /* 错误结束,没收到'(' */
- }
- if (fover == 0)break; /* 到末尾了,退出 */
- }
- else if (*strtemp == '"')
- {
- nchar = !nchar;
- }
- if (fover == 0) /* 函数名还没接收完 */
- {
- if (*strtemp != ' ') /* 空格不属于函数名 */
- {
- *fname = *strtemp; /* 得到函数名 */
- fname++;
- }
- }
- else /* 已经接受完了函数名了. */
- {
- if (*strtemp == ',')
- {
- temp = 1; /* 使能增加一个参数 */
- pcnt++;
- }
- else if (*strtemp != ' ' && *strtemp != '(')
- {
- if (pcnt == 0 && fplcnt < 5) /* 当第一个参数来时,为了避免统计void类型的参数,必须做判断. */
- {
- fpname[fplcnt] = *strtemp; /* 记录参数特征. */
- fplcnt++;
- }
- temp++; /* 得到有效参数(非空格) */
- }
- if (fover == 1 && temp == 2)
- {
- temp++; /* 防止重复增加 */
- parmnum++; /* 参数增加一个 */
- }
- }
- strtemp++;
- }
- if (parmnum == 1) /* 只有1个参数. */
- {
- fpname[fplcnt] = '\0'; /* 加入结束符 */
- if (usmart_strcmp(fpname, "void") == 0)parmnum = 0; /* 参数为void,表示没有参数. */
- }
- *pnum = parmnum;/* 记录参数个数 */
- *fname = '\0'; /* 加入结束符 */
- return res; /* 返回执行结果 */
- }
复制代码
|
|