自己动手实现命令行解析器

一、介绍
嵌入式里面经常会自己做命令行,这里分享一个命令解析器代码实现,比如单片机串口命令行,或者网络命令行,这里测试使用的是ubuntu linux

二、代码实现

mycmd.c

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		头文件区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include <stdio.h>
#include <string.h>

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		接口定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
typedef struct 
{
	char *cmd;
	void (*cmd_func)();
}mycmd_def;

#define MAX_CMD_NUM 30
#define CMD_BUFF_SIZE 1024
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		变量定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
mycmd_def mycmd_queue[MAX_CMD_NUM] = {0};
static volatile short cur_cmd_num = 0;
static char cmd_buff[CMD_BUFF_SIZE] = {0};
static volatile int input_cmd_len = 0;
static volatile char cmd_input_flag = 0;

enum {
	CMD_RESOLVER_IDLE = 0,
	CMD_RESOLVER_INPUT,
	CMD_RESOLVER_BUSY,
	CMD_RESOLVER_DONE
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

																		函数定义区

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

void print_version_Executive_function()
{
	const char software_version[] = "v0.1";

	printf("software version:%s\n",software_version);
	//---
}

void download_Executive_function()
{
	printf("download app\n");
	//---
}

//cmd:String command  
//cmd_fun:the callback function
int addcmd(char *cmd, void (*cmd_func)())
{
	if(cur_cmd_num >= MAX_CMD_NUM)
		return -1;
	mycmd_queue[cur_cmd_num].cmd = cmd;
	mycmd_queue[cur_cmd_num].cmd_func = cmd_func;
	cur_cmd_num++;

	return 0;
}

void Mycmd_Init(void)
{
	//init parameter
	cmd_input_flag = CMD_RESOLVER_IDLE;
	memset(cmd_buff, 0, CMD_BUFF_SIZE);
	memset(mycmd_queue, 0, sizeof(mycmd_def)*MAX_CMD_NUM);
	cur_cmd_num = 0;
	//add cmd to cmd queue
	addcmd("print ver", print_version_Executive_function);
	addcmd("download", download_Executive_function);
}

int mystrcmp(char *s1, char *s2, int len)
{
	int i; 

	printf("s1 %s s2 %s len %d\n", s1, s2, len);
	for(i = 0; i < len; i++)
	{
		if(s1[i] == '\0' || s2[i] == '\0')
			break;
		if(s1[i] != s2[i])
			return 0;
	}
	if(s1[i] != s2[i])
		return 0;
	else
		return 1;
}

void Mycmd_Run(void)
{
	int i = 0;
	if(cmd_input_flag == CMD_RESOLVER_IDLE)
		return ;
	cmd_input_flag = CMD_RESOLVER_BUSY;
	for(i = 0; i < cur_cmd_num; i++)
	{
		if(mystrcmp(mycmd_queue[i].cmd, cmd_buff, input_cmd_len) == 1)
		{
			mycmd_queue[i].cmd_func();
			cmd_input_flag = CMD_RESOLVER_IDLE;
			input_cmd_len = 0;
			return;
		}
	}
	printf("no surport cmd\n");
	cmd_input_flag = CMD_RESOLVER_IDLE;
	input_cmd_len = 0;
}

int input_cmd(char *cmd, int len)
{
	if( cmd == NULL || 
		len == 0 ||
		cmd_input_flag == CMD_RESOLVER_BUSY
	)
	{
		return -1;
	}
	memset(cmd_buff, 0, CMD_BUFF_SIZE);
	memcpy(cmd_buff, cmd, len);
	input_cmd_len = len;
	cmd_input_flag = CMD_RESOLVER_INPUT;

	return 0;
}

mycmd.h

#ifndef __MYCMD_H
#define __MYCMD__H

void Mycmd_Init(void);
void Mycmd_Run(void);
void input_cmd(char *cmd, int len);

#endif

main.c

#include <stdio.h>
#include "mycmd.h"

int main()
{
    char buff[100] = {0};
    Mycmd_Init();

    while(1)
    {
        printf("请输入命令\n");
        scanf("%s", buff);
        input_cmd(buff, strlen(buff));
        Mycmd_Run();
    }
    
    return 0;
}

编译脚本
build.sh

echo "delet main"

rm -rf main

gcc main.c mycmd.c -o main -w

echo "build ok"
echo "run..."

./main

结果
在这里插入图片描述

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值