Command(命令模式)

1、定义:

         将一个请求封装成一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。

2、结构图:

             

3、协作角色:

       Command 声明执行操作的接口。

       ConcreteCommand 将一个对象绑定与一个动作,调用接受者相关的操作,以实现Execute()

      Client 创建一个具体的对象并设定它的接收者

      Invoker 要求该命令执行这个请求,

     Receiver知道如何实施与一个请求相关的操作,任何类都可能成为一个接收者

4、适用性:

       对象可抽象出待执行的动作以参数化别的对象。

       在不同时刻指定、排列和执行请求。

        支持取消操作。

       支持修改日志

       用构建在原语操作上的高层操作构造一个系统

5、实现:

       1、需求:uboot上其命令按照一定的格式封装成一个对象,供客户在控制台通过输入命令调用。

       2、实现(模拟uboot命令):

 command.h

#ifndef __COMMAND_H__
#define __COMMAND_H__

struct cmd_tbl_s {
	char *name;
	int maxargs;
	int repeatable;
	int (*cmd)(struct cmd_tbl_s *, int , int ,char *[]);
	char *usage;
	char *help;
};
typedef struct cmd_tbl_s cmd_tbl_t;

int cmd_init();
int command_add(cmd_tbl_t *cmdtp);
int cmd_del(cmd_tbl_t *cmdtp);
int cmd_find_item(cmd_tbl_t **cmdtp,char *name);





#define U_BOOT_CMD(name,maxargs,rep,cmd,usage,help) \
	cmd_tbl_t __u_boot_cmd_##name = {#name, maxargs, rep, cmd, usage, help}

#define CONFIG_SYS_MAXARGS      16
#define cmd_usage(cmdtp,st) \
	do {	\
			printf("%s--%s\n",((st *)cmdtp)->name,((st *)cmdtp)->usage); \
			if(!((st *)cmdtp)->help)							\
			{											\
				printf("no help\n");					\
				return 1;								\
			}											\
			printf("%s \n",((st *)cmdtp)->help);				\
			return 0;									\
	}while(0)


#endif


cmd_nand.c

#include <stdio.h>
#include <string.h>
#include "command.h"

int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char *cmd;
	printf("%s %d\n",__func__, __LINE__);

	if(argc < 2)
		goto usage;
	
	cmd = argv[1];
	if(strcmp(cmd, "info") == 0)
	{
		printf("\nprint nand %s\n",cmd);
		return 0;
	}
	else if((strncmp(cmd, "read",4) == 0)|| (strncmp(cmd, "write", 5) == 0))
	{
		printf("\nnand %s\n",cmd);
		return 0;
	}
	else
	{
		printf("\nnand %s\n",cmd);
	}
	
usage:
	printf("cmdtp %p\n",cmdtp);
	cmd_usage(cmdtp,cmd_tbl_t);
}

U_BOOT_CMD(nand, CONFIG_SYS_MAXARGS, 1, do_nand,
	"NAND sub-system",
	"info - show available NAND devices\n"
	"nand read - addr off|partition size\n"
	"nand write - addr off|partition size\n"
	"    read/write 'size' bytes starting at offset 'off'\n"
	"    to/from memory address 'addr', skipping bad blocks.\n"
);
void register_nand()
{
	command_add(&__u_boot_cmd_nand);
}

 

cmd_env.c

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

char env[256] = "cmd env test\n";
int do_env(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
{
	char *cmd = NULL;
	if(argc < 2)
		goto usage;

	cmd = argv[1];
	
	if(strcmp(cmd, "show") == 0)
	{
		printf("\nENV is :\n %s\n",env);
		return 0;
	}
	else if(strcmp(cmd, "store") == 0)
	{
		if(argc < 3)
			goto usage;
		sprintf(env,"%s",argv[2]);
		return 0;
	}
usage:
	cmd_usage(cmdtp,cmd_tbl_t);
	
}


U_BOOT_CMD(env,CONFIG_SYS_MAXARGS,1,do_env,
	"ENV sub-system",
	"print env - env show\n"
	"env store [string]-env store\n");

void register_env()
{
	command_add(&__u_boot_cmd_env);
}

 

cmd.c

#include <stdio.h>
#include <string.h>
#include "command.h"

#define CMD_NUM		10
struct cmd 
{
	cmd_tbl_t *command;
	int flag;
};
struct cmd  command[CMD_NUM];

int cmd_init()
{
	memset(command,0, sizeof(command));
	
	register_nand();
	register_env();
}

int command_add(cmd_tbl_t *cmdtp)
{
	unsigned int i;
	
	if(NULL == cmdtp)
		return 1;

	for(i = 0; i < CMD_NUM; i++)
	{
		if(command[i].flag == 1)
			continue;
		else
			break;
	}

	if(i == CMD_NUM)
	{
		printf("command is full");
		return 1;
	}
	
	command[i].command = cmdtp;
	command[i].flag = 1;

	return 0;
}


int cmd_del(cmd_tbl_t *cmdtp)
{
	unsigned int i;
	
	if(NULL == cmdtp)
		return 1;

	for(i = 0; i < CMD_NUM; i++)
	{
		if(command[i].flag == 1)
		{
			if(strcmp(command[i].command->name, cmdtp->name) == 0)
			{
				memset(&command[i], 0, sizeof(struct cmd));
				return 0;
			}
		}
	}

	return 1;
}

int cmd_find_item(cmd_tbl_t **cmdtp,char *name)
{
	
	unsigned int i;
	if(NULL == cmdtp)
		return 1;
	
	for(i = 0; i < CMD_NUM; i++)
	{
		if(command[i].flag == 1)
		{
			if(strcmp(command[i].command->name, name) == 0)
			{
				
				printf("%s %d cmdtp.cmd %p\n",__func__, __LINE__,command[i].command->cmd);
				*cmdtp = command[i].command;
				return 0;
			}
		}
	}

	return 1;
}


 

 

client.c

#include <stdio.h>
#include <string.h>
#include "command.h"

int check_cmd(char *cmd)
{
	unsigned int len;
	unsigned int i;
	
	len = strlen(cmd);
	for(i = 0; i < len - 1; i++)
	{
		if((cmd[i] >= 'a')&&(cmd[i] <= 'z'))
			continue;
		else
			return 1;
	}
	return 0;
}
int main(int argc, char *argv[])
{
	cmd_tbl_t *cmdtp = NULL;
	char *cmd;

	if(argc < 3)
	{
		return 1;
	}
	
	cmd = argv[1];
	if(check_cmd(cmd))
		return 2;
	cmd_init();
	if(cmd_find_item(&cmdtp,cmd))
		return 3;
	
	printf("%s %d cmdtp.cmd %p\n",__func__, __LINE__,cmdtp->cmd);
	cmdtp->cmd(cmdtp, 0, argc - 1,&argv[1]);
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值