1
0
mirror of https://github.com/NevermindZZT/letter-shell.git synced 2025-01-21 10:02:54 +08:00
letter-shell/shell_ext.c

299 lines
5.7 KiB
C

/**
* @file shell_ext.c
* @author Letter (NevermindZZT@gmail.com)
* @brief shell extensions
* @version 1.0.0
* @date 2019-01-05
*
* @Copyright (c) 2019 Letter
*
*/
#include "shell.h"
#include "shell_ext.h"
/**
* @brief 判断数字进制
*
* @param string 参数字符串
* @return NUM_Type 进制
*/
static NUM_Type shellExtNumType(char *string)
{
char *p = string;
NUM_Type type = NUM_TYPE_INT;
if ((*p == '0') && ((*(p + 1) == 'x') || (*(p + 1) == 'X')))
{
type = NUM_TYPE_HEX;
}
else if ((*p == '0') && ((*(p + 1) == 'b') || (*(p + 1) == 'B')))
{
type = NUM_TYPE_BIN;
}
else if (*p == '0')
{
type = NUM_TYPE_OCT;
}
else
{
while (*p++)
{
if (*p == '.' && *(p + 1) != 0)
{
type = NUM_TYPE_FLOAT;
break;
}
}
}
return type;
}
/**
* @brief 字符转数字
*
* @param code 字符
* @return char 数字
*/
static char shellExtToNum(char code)
{
if ((code >= '0') && (code <= '9'))
{
return code -'0';
}
else if ((code >= 'a') && (code <= 'f'))
{
return code - 'a' + 10;
}
else if ((code >= 'A') && (code <= 'F'))
{
return code - 'A' + 10;
}
else
{
return 0;
}
}
/**
* @brief 解析字符参数
*
* @param string 字符串参数
* @return char 解析出的字符
*/
static char shellExtParseChar(char *string)
{
char *p = string + 1;
char value = 0;
if (*p == '\\')
{
switch (*(p + 1))
{
case 'b':
value = '\b';
break;
case 'r':
value = '\r';
break;
case 'n':
value = '\n';
break;
case 't':
value = '\t';
break;
case '0':
value = 0;
break;
default:
value = *(p + 1);
break;
}
}
else
{
value = *p;
}
return value;
}
/**
* @brief 解析字符串参数
*
* @param string 字符串参数
* @return char* 解析出的字符串
*/
static char* shellExtParseString(char *string)
{
char *p = string;
unsigned short index = 0;
if (*string == '\"')
{
p = ++string;
}
while (*p)
{
if (*p == '\\')
{
*(string + index) = shellExtParseChar(p - 1);
p++;
}
else if (*p == '\"')
{
*(string + index) = 0;
}
else
{
*(string + index) = *p;
}
p++;
index ++;
}
*(string + index) = 0;
return string;
}
/**
* @brief 解析数字参数
*
* @param string 字符串参数
* @return unsigned int 解析出的数字
*/
static unsigned int shellExtParseNumber(char *string)
{
NUM_Type type = NUM_TYPE_INT;
char radix = 10;
char *p = string;
char offset = 0;
signed char sign = 1;
unsigned int valueInt = 0;
if (*string == '-')
{
sign = -1;
}
type = shellExtNumType(string + ((sign == -1) ? 1 : 0));
switch ((char)type)
{
case NUM_TYPE_HEX:
radix = 16;
offset = 2;
break;
case NUM_TYPE_OCT:
radix = 8;
offset = 1;
break;
case NUM_TYPE_BIN:
radix = 2;
offset = 2;
break;
default:
break;
}
p = string + offset + ((sign == -1) ? 1 : 0);
if (type != NUM_TYPE_FLOAT)
{
while (*p)
{
valueInt = valueInt * radix + shellExtToNum(*p);
p++;
}
return valueInt * sign;
}
return 0;
}
/**
* @brief 解析参数
*
* @param string 参数
* @return unsigned int 解析结果
*/
unsigned int shellExtParsePara(char *string)
{
if (*string == '\'' && *(string + 1))
{
return (unsigned int)shellExtParseChar(string);
}
else if (*string == '-' || (*string >= '0' && *string <= '9'))
{
return (unsigned int)shellExtParseNumber(string);
}
else if (*string)
{
return (unsigned int)shellExtParseString(string);
}
return 0;
}
/**
* @brief 执行命令
*
* @param function 执行命令的函数
* @param argc 参数个数
* @param argv 参数
* @return int 返回值
*/
int shellExtRun(shellFunction function, int argc, char *argv[])
{
switch (argc)
{
case 1:
function();
break;
case 2:
function(shellExtParsePara(argv[1]));
break;
case 3:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]));
break;
case 4:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
shellExtParsePara(argv[3]));
break;
case 5:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]));
break;
case 6:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
shellExtParsePara(argv[5]));
break;
case 7:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
shellExtParsePara(argv[5]), shellExtParsePara(argv[6]));
break;
case 8:
function(shellExtParsePara(argv[1]), shellExtParsePara(argv[2]),
shellExtParsePara(argv[3]), shellExtParsePara(argv[4]),
shellExtParsePara(argv[5]), shellExtParsePara(argv[6]),
shellExtParsePara(argv[7]));
break;
default:
return -1;
// break;
}
return 0;
}