Codejie's C++ Space

Using C++

轮子:CmdChannel的CmdParser


    CmdParser是用于分解和分析命令输入的,说是一个Parser,实际很简单,就是将命令分解,然后将分解出来的命令字串跟已经'regist'的命令字串进行一一的比较,找到就返回注册命令的指针,并传入相应的参数(这部分代码在TelnetServer中);找不到就执行默认的UnknownCmdProc。


#ifndef __CCCMD_H__
#define __CCCMD_H__

#include 
"CCDataType.h"


extern int cc_TelnetServer_ClientWriteText(SOCKET s, const char* text);


extern int cc_CmdParser_Parser(struct _cc_telnet_clientdata* client, struct _cc_cmddata** cmd, int* argc, char argv[][CC_SIZE_CMD]);
extern int cc_CmdParser_UnknownCmd(struct _cc_telnet_clientdata* client, const char* cmd);

extern int cc_RegCmd(const char* cmd, const char*help, const _cc_cmdcallback callback);
extern int cc_RegDefaultCmds();

extern int cc_CmdOutput(struct _cc_telnet_clientdata* client, const char* fmt, );

extern int cc_cmd_exit(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_help(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_list(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);
extern int cc_cmd_version(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD]);


#endif



#include 
<stdarg.h>

#include 
"CCCmd.h"

int cc_CmdParser_Search(const char* str, struct _cc_cmddata** cmd)
{
    
struct _cc_cmddata* c = cc_Global.cmd.cmd;
    
while(c != NULL)
    
{
        
if(strcmp(c->cmd, str) == 0)
        
{
            (
*cmd) = c;
            
return 0;
        }

        c 
= c->next;
    }

    
    
return -1;
}


int cc_CmdParser_Parser(struct _cc_telnet_clientdata* client, struct _cc_cmddata** cmd, int* argc, char argv[][CC_SIZE_CMD])
{
    
char str[CC_SIZE_CMD];
    
char* token = NULL;
    
char* sep = ",";

    memset(str, 
0sizeof(str));
    strncpy(str, client
->buf, client->recv - 2);
    
    token 
= strtok(str, sep);
    
if(token == NULL)
        
return -1;
    
    
if(cc_CmdParser_Search(token, cmd) != 0)
    
{
        cc_CmdParser_UnknownCmd(client, token);
        
return -1;
    }

    
    (
*argc) = 0;
    token 
= strtok(NULL, sep);
    
while(token != NULL)
    
{
        strncpy(
&argv[(*argc)], token, CC_SIZE_CMD);
        
++ (*argc);
        token 
= strtok(NULL, sep);
    }


    
return 0;
}


int cc_CmdParser_UnknownCmd(struct _cc_telnet_clientdata* client, const char* cmd)
{
    cc_CmdOutput(client, 
"Unknown command - %s\r\n", cmd);

    
return 0
}


int cc_RegDefaultCmds()
{
    cc_RegCmd(
".version""display version info.", cc_cmd_version);
    cc_RegCmd(
".exit""exit the connection.", cc_cmd_exit);
    cc_RegCmd(
".help""display help info of command.", cc_cmd_help);
    cc_RegCmd(
".list""list all connections.", cc_cmd_list);

    
return 0;
}



int cc_RegCmd(const char* cmd, const char* help, const _cc_cmdcallback callback)
{
    
struct _cc_cmddata* tmp = NULL;
    
struct _cc_cmddata* c = (struct _cc_cmddata*)malloc(sizeof(struct _cc_cmddata));
    c
->callback = callback;
    strncpy(c
->cmd, cmd, sizeof(c->cmd));
    strncpy(c
->help, help, sizeof(c->help));
    c
->next = NULL;

    
if(cc_Global.cmd.cmd == NULL)
    
{
        cc_Global.cmd.cmd 
= c;
    }

    
else
    
{
        tmp 
= cc_Global.cmd.cmd;
        
while(tmp->next != NULL)
        
{
            tmp 
= tmp->next;
        }

        tmp
->next = c;
    }


    
return 0;
}


int cc_CmdOutput(struct _cc_telnet_clientdata* client, const char* fmt, )
{
    
char buf[CC_SIZE_CMD];
    
int len = -1;
    va_list args;

    memset(buf, 
0sizeof(buf));
    va_start(args, fmt);
    len 
= vsprintf(buf, fmt, args);
    va_end(args);
    
return cc_TelnetServer_ClientWrite(client->sock, buf, len);

//    len = sprintf(buf, fmt, __VA_ARGS__);
}


/* ----------------------------- */
int cc_cmd_exit(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])
{
    cc_CmdOutput(client, 
"bye.\r\n");
    
return -1;    
}


int cc_cmd_help(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])
{
    
struct _cc_cmddata* tmp = cc_Global.cmd.cmd;
    
while(tmp != NULL)
    
{
        
if(argc > 0)
        
{
            
if(strncmp(tmp->cmd, argv[0], sizeof(tmp->cmd)) == 0)
            
{
                cc_CmdOutput(client, 
"%s : %s\r\n", tmp->cmd, tmp->help);

                
return 0;
            }

        }

        
else
        
{
            cc_CmdOutput(client, 
"%s : %s\r\n", tmp->cmd, tmp->help);
        }

        tmp 
= tmp->next;
    }

    
return 0;
}


int cc_cmd_list(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])
{
    
struct _cc_telnet_clientdata* tmp = cc_Global.telnet.client;

    
while(tmp != NULL)
    
{
        
        cc_CmdOutput(client, 
"conn %d : %s:%d in %s", tmp->index, tmp->ip, tmp->port, asctime(gmtime(&tmp->updated)));
        tmp 
= tmp->next;
    }

    cc_CmdOutput(client, 
"\r\n");
    
return 0;
}


int cc_cmd_version(struct _cc_telnet_clientdata* client, int argc, const char (*argv)[CC_SIZE_CMD])
{
    cc_CmdOutput(client, 
"CmdChannel library v0.0.0.2 by Jie.(codejie@gmail.com).\r\n");
    
return 0;
}

posted on 2009-12-16 23:01 codejie 阅读(412) 评论(0)  编辑 收藏 引用 所属分类: C++轮子精神


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


公告

Using C++

导航

统计

留言簿(73)

随笔分类(513)

积分与排名

最新评论

阅读排行榜

评论排行榜