Linux

[device driver] command line

aucd29 2013. 9. 26. 20:51
#include <stdio.h>
#define MAX_ARGS 20

// Bool 형 정의
typedef int bool;

#define true 1
#define false 0

struct _CMD_TBL { // 구조체 선언
        char *cmd; // 예약된 명령어
        bool (*run)(struct _CMD_TBL *cptr, int argc, char **argv); // 1. 함수 pointer의 proto type 선언
        // 구조체의 선언이 함수 pointer와 동일
        char *usage; // 해당되는 명령어의 사용법
        char *help;
        char *helpMore;
};

#define CMD_TBL_TEST {"test", DoTest, 0, 0, 0} // 2. 주소 대입(record의 초기화)
#define CMD_TBL_XXX {"xxx", DoXxx, 0, 0, 0} // 2
#define CMD_TBL_OPR {"opr", DoOpr, 0, 0, 0}
#define CMD_TBL_END {0, 0, 0, 0, 0}

//CMD_TBL cmdTbl[] = {

void DisplayPrompt(char *prompt);
bool DoPrintfHelp(int argc, char **argv);
int GetCommand(char *cmd, int len, int timeout);
int GetArgs(char *s, char **argv);
void command_main(void);

//bool SungJuk(CMD_TBL) *cptr, int argc, char **argv);
bool DoTest(struct _CMD_TBL *cptr, int argc, char **argv);
bool DoXxx(struct _CMD_TBL *cptr, int argc, char **argv); // 3
bool DoOpr(struct _CMD_TBL *cptr, int argc, char **argv);

struct _CMD_TBL cmdTbl[] = { // record 할당 & 초기화
        CMD_TBL_TEST, //record의 초기값
        CMD_TBL_XXX, // 1
        CMD_TBL_OPR,
        CMD_TBL_END
};

//int main(int argc, int **argv)
int main()
{
        printf("\n\n Test for Command Line\n\n");
        command_main();        
        return 0;
}

void DisplayPrompt(char *prompt)
{
        if (prompt == NULL)
                printf ("> ");
        else
                printf (prompt);
}

void command_main(void)
{
        char cmd[128];
        int argc = 0;
        char *argv[MAX_ARGS];
        struct _CMD_TBL *cptr; // pointer 선언
        for ( ; ; )
        {
                DisplayPrompt("BaRaMiR> ");

                // wait an hour to get a command.
                GetCommand(cmd, 128, 3600);
                if (!cmd || !cmd[0]) continue;

                argc = GetArgs(cmd, argv); // 구조체를 사용하는 poiner 초기화
                for (cptr = cmdTbl; cptr -> cmd; cptr++)
                {
                        if (!strcmp(argv[0], cptr -> cmd))
                        {
                                if (cptr -> run != 0)
                                {
                                        (cptr -> run)(cptr, argc, argv); // 구조체 pointer 사용
                                        // DoTest 실행
                                        break;
                                }
                        }
                }
                if(!strcmp(argv[0], "help") || !strcmp(argv[0], "?"))
                        DoPrintfHelp(argc, argv);
                else if (!(cptr -> cmd))
                        printf("\tUnknown command : %s\n", argv[0]);
                if (!strcmp(argv[0], "end"))
                        break;
        }
} // command_main

int GetCommand(char *cmd, int len, int timeout)
{
        char c;
        int i, rdCnt, rdMax = len - 1;
        for (rdCnt = 0, i = 0; rdCnt < rdMax; )
        {
                c = getchar();
                if ((c == '\r') || (c == '\n'))
                {
                        cmd[i++] = '\0';
                        printf ("\n"); // print newline
                        return rdCnt; // Enter key를 입력 받으면 종료
                }
                else if (c == '\b')
                {
                        if (i > 0)
                        {
                                i--;
                                rdCnt--; // cursor one position back.
                                printf ("\b \b");
                        }
                }
                else
                {
                        cmd[i++] = c;
                        rdCnt++; // print character
                        printf("%c", c);
                }
        }
        return (rdCnt); // 받은 숫자가 return된다
} // GetCommand.

int GetArgs(char *s, char **argv) // 이중 pointer 사용
{ // s는 배열을 가리키는 pointer
        int args = 0;
        if (!s || (*s == '\0'))
                return 0;
        while (args < MAX_ARGS)
        {
                // skip space and tab.
                while ((*s == ' ') || (*s == '\t'))
                        s++; // check end of line.
                if (*s == '\0')
                {
                        argv[args] = 0;
                        return args;
                } // start get arg.
                argv[args++] = s; // remove ' ' and '\t'.
                while (*s && (*s != ' ') && (*s != '\t'))
                        s++; // end of line.
                if (*s == '\0')
                {
                        argv[args] = 0;
                        return args;
                }
        *s++ = '\0';
        }
        return args;
} // GetArgs.

bool DoPrintfHelp(int argc, char **argv)
{
        struct _CMD_TBL *cptr;
        if (argc == 1)
        {
                //printf ("Help for " PACKAGE "-" VERSION "\n");
                printf ("The following commands are supported :\n");
                printf ("help : Help for commands.\n");
                for (cptr = cmdTbl; cptr -> cmd; cptr++)
                {
                        if (cptr -> helpMore)
                                printf (cptr -> helpMore);
                }
                printf ("\n");
        }
        else
                printf ("\tUnknown command : %s\n", argv[0]);
        return true;
}

bool DoTest(struct _CMD_TBL *cptr, int argc, char **argv)
{
        printf ("This is test. \n");
//        xxx_main();
        return true;
}

bool DoXxx(struct _CMD_TBL *cptr, int argc, char **argv)
{
        printf ("This is Xxx. \n");
//        xxx_menu();
        return true;
} // 4

bool DoOpr(struct _CMD_TBL *cptr, int argc, char **argv)
{
        printf ("This is Opr. \n");
//        opr_main();
        return true;
}