⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd.c

📁 ms-linux 基于Linux0.01版,可以在ADS上编译,是嵌入式操作系统编程初学者学习的好代码.
💻 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 + -