📄 cmd.c
字号:
/*
* cmd, kernel module, console shell,
* similar to Cisco command shell, by risonhan.
* email: risonhan@sina.com
*/
#include "cmd.h"
#include "iofn.h"
static int scan(struct cmd *cmd_ptr,char *name);
static int scan_0(struct cmd *cmd_ptr,char *name);
static int value_argc;
static char *value_argv[32]; /* how many args is best? */
static struct cmd *cmd_root; /* note 'static' here */
static char outbuf[128];
/*
* process the incoming command,main routine of cmd
*/
int cmd_process(int argc,char *argv[])
{
int i,position,scan_state,offset;
struct cmd *cur_cur,*cur_top;
char tmp_buf[128];
/*
* meaning of the scan_state:
* 0 - uncompleted command
* 1 - unknown command
* 2 - token OK
* 3 - value OK
* 4 - help
* 5 - too many arguments
*/
value_argc=0;
scan_state=0;
cur_cur=cur_top=cmd_root;
for(i=0;i<argc;i++)
{
switch (cur_cur->type)
{
case TOKEN:
case TOKEN_LEAF:
offset=scan(cur_cur,argv[i]);
if(offset>=0)
{
if((cur_cur+offset)->type==TOKEN)
{
/* find a available one in this level */
if(i<argc-1)
{
/* go ahead */
cur_top=(cur_cur+offset)->next;
cur_cur=cur_top;
}
else
{
/* i=argc-1 here,the last arg */
/* args end,but not reach leaf */
scan_state=0;
}
}
else /* type==TOKEN_LEAF */
{
if(i<argc-1)
{
/* reach leaf,but args not end */
scan_state=5;
}
else
{
/* find a available one,OK! */
scan_state=2;
cur_cur+=offset;
}
}
}
else /* offset<0 */
{
/* if it's a help request */
if(!strcmp(argv[i], "?"))
{
scan_state=4;
}
else
{
scan_state=1;
}
}
break;
case VALUE:
case VALUE_LEAF:
if(!strcmp(argv[i], "?"))
{
scan_state=4;
}
else
{
/* save arg pointer */
value_argv[value_argc]=argv[i];
value_argc++;
if(cur_cur->type==VALUE)
{
if(i<argc-1)
{
/* go ahead */
cur_top=cur_cur->next;
cur_cur=cur_top;
}
else
{
/* value end, but not reach leaf */
scan_state=0;
}
}
else /* type==VALUE_LEAF */
{
if(i<argc-1)
{
/* reach leaf,but args not end */
scan_state=5;
}
else
{
/* value OK! but we don't check whether it's valid */
scan_state=3;
}
}
}
break;
}/* switch */
if((scan_state==1)||(scan_state==4)||(scan_state==5))
{
/* needn't go on,abort */
break;
}
}/* for */
switch(scan_state)
{
case 0: /* uncompleted command */
sprintf(tmp_buf,"%s","");
for (i=0;i<argc;i++)
{
strcat(tmp_buf,argv[i]);
strcat(tmp_buf," ");
}
sprintf(outbuf,"uncompleted command, type: %s ? \r\n",tmp_buf);
output(outbuf);
break;
case 1: /* unknown command */
sprintf(tmp_buf,"%s","");
/* save position from where it's unknown */
position=i;
for (i=0;i<position;i++)
{
strcat(tmp_buf,argv[i]);
strcat(tmp_buf," ");
}
sprintf(outbuf,"unknown command, type: %s ? \r\n",tmp_buf);
output(outbuf);
break;
case 2: /* token OK */
if(cur_cur->func)
{
(*cur_cur->func)(argc,argv);
}
break;
case 3: /* value OK */
if(cur_cur->func)
{
(*cur_cur->func)(value_argc,value_argv);
}
break;
case 4: /* help */
cur_cur=cur_top;
while(cur_cur->type)
{
sprintf(outbuf,"%-15s %s\r\n",cur_cur->name,cur_cur->tip);
output(outbuf);
cur_cur++;
}
sprintf(outbuf,"%-15s %s\r\n","?","help");
output(outbuf);
break;
case 5: /* too many arguments*/
output("too many arguments\r\n");
break;
}
return 0;
}
/*
* simple scan,only compare entirely name
*/
static int scan_0(struct cmd *cmd_ptr,char *name)
{
int i;
for(i=0;;i++)
{
if(cmd_ptr->type==0)
return -1;
if(!strcmp(cmd_ptr->name, name))
return i;
cmd_ptr++;
}
}
/*
* nice scan,try to find the best match one
*/
static int scan(struct cmd *cmd_ptr,char *name)
{
int best,best_match_chars,i,j,name_len;
best=-1;
best_match_chars=0;
name_len=strlen(name);
for(i=0;cmd_ptr->type;i++)
{
if(name_len<=(int)strlen(cmd_ptr->name))
{
for(j=0;j<name_len;j++)
{
if((name[j]!=(cmd_ptr->name)[j]))
{
break;
}
}
if(j==name_len)
{
if(j>best_match_chars)
{
best_match_chars=j;
best=i;
}
}
}
cmd_ptr++;
}/* for */
return best;
}
void cmd_root_set(struct cmd *root)
{
cmd_root=root;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -