parser.c

来自「lustre 1.6.5 source code」· C语言 代码 · 共 773 行 · 第 1/2 页

C
773
字号
        interactive = init_input();        while(!done) {                line = readline(interactive ? parser_prompt : NULL);                if (!line) break;                s = skipwhitespace(line);                if (*s) {                        add_history(s);                        rc = execute_line(s);                }                /* stop on error if not-interactive */                if (rc != 0 && !interactive) {                        if (save_error == 0)                                save_error = rc;                        if (!ignore_errors)                                done = 1;                }                free(line);        }        if (save_error)                rc = save_error;        return rc;}/* sets the parser prompt */void Parser_init(char * prompt, command_t * cmds){        done = 0;        top_level = cmds;        if (parser_prompt) free(parser_prompt);        parser_prompt = strdup(prompt);}/* frees the parser prompt */void Parser_exit(int argc, char *argv[]){        done = 1;        free(parser_prompt);        parser_prompt = NULL;}/* convert a string to an integer */int Parser_int(char *s, int *val){        int ret;        if (*s != '0')                ret = sscanf(s, "%d", val);        else if (*(s+1) != 'x')                ret = sscanf(s, "%o", val);        else {                s++;                ret = sscanf(++s, "%x", val);        }        return(ret);}void Parser_qhelp(int argc, char *argv[]) {        printf("Available commands are:\n");        print_commands(NULL, top_level);        printf("For more help type: help command-name\n");}int Parser_help(int argc, char **argv){        char line[1024];        char *next, *prev, *tmp;        command_t *result, *ambig;        int i;        if ( argc == 1 ) {                Parser_qhelp(argc, argv);                return 0;        }        line[0]='\0';        for ( i = 1 ;  i < argc ; i++ ) {                strcat(line, argv[i]);        }        switch ( process(line, &next, top_level, &result, &prev) ) {        case CMD_COMPLETE:                fprintf(stderr, "%s: %s\n",line, result->pc_help);                break;        case CMD_NONE:                fprintf(stderr, "%s: Unknown command.\n", line);                break;        case CMD_INCOMPLETE:                fprintf(stderr,                        "'%s' incomplete command.  Use '%s x' where x is one of:\n",                        line, line);                fprintf(stderr, "\t");                for (i = 0; result->pc_sub_cmd[i].pc_name; i++) {                        fprintf(stderr, "%s ", result->pc_sub_cmd[i].pc_name);                }                fprintf(stderr, "\n");                break;        case CMD_AMBIG:                fprintf(stderr, "Ambiguous command \'%s\'\nOptions: ", line);                while( (ambig = find_cmd(prev, result, &tmp)) ) {                        fprintf(stderr, "%s ", ambig->pc_name);                        result = ambig + 1;                }                fprintf(stderr, "\n");                break;        }        return 0;}void Parser_printhelp(char *cmd){        char *argv[] = { "help", cmd };        Parser_help(2, argv);}/************************************************************************* * COMMANDS                                                              * *************************************************************************/static void print_commands(char * str, command_t * table) {        command_t * cmds;        char         buf[80];        for (cmds = table; cmds->pc_name; cmds++) {                if (cmds->pc_func) {                        if (str) printf("\t%s %s\n", str, cmds->pc_name);                        else printf("\t%s\n", cmds->pc_name);                }                if (cmds->pc_sub_cmd) {                        if (str) {                                sprintf(buf, "%s %s", str, cmds->pc_name);                                print_commands(buf, cmds->pc_sub_cmd);                        } else {                                print_commands(cmds->pc_name, cmds->pc_sub_cmd);                        }                }        }}char *Parser_getstr(const char *prompt, const char *deft, char *res,                    size_t len){        char *line = NULL;        int size = strlen(prompt) + strlen(deft) + 8;        char *theprompt;        theprompt = malloc(size);        assert(theprompt);        sprintf(theprompt, "%s [%s]: ", prompt, deft);        line  = readline(theprompt);        free(theprompt);        if ( line == NULL || *line == '\0' ) {                strncpy(res, deft, len);        } else {                strncpy(res, line, len);        }        if ( line ) {                free(line);                return res;        } else {                return NULL;        }}/* get integer from prompt, loop forever to get it */int Parser_getint(const char *prompt, long min, long max, long deft, int base){        int rc;        long result;        char *line;        int size = strlen(prompt) + 40;        char *theprompt = malloc(size);        assert(theprompt);        sprintf(theprompt,"%s [%ld, (0x%lx)]: ", prompt, deft, deft);        fflush(stdout);        do {                line = NULL;                line = readline(theprompt);                if ( !line ) {                        fprintf(stdout, "Please enter an integer.\n");                        fflush(stdout);                        continue;                }                if ( *line == '\0' ) {                        free(line);                        result =  deft;                        break;                }                rc = Parser_arg2int(line, &result, base);                free(line);                if ( rc != 0 ) {                        fprintf(stdout, "Invalid string.\n");                        fflush(stdout);                } else if ( result > max || result < min ) {                        fprintf(stdout, "Error: response must lie between %ld and %ld.\n",                                min, max);                        fflush(stdout);                } else {                        break;                }        } while ( 1 ) ;        if (theprompt)                free(theprompt);        return result;}/* get boolean (starting with YyNn; loop forever */int Parser_getbool(const char *prompt, int deft){        int result = 0;        char *line;        int size = strlen(prompt) + 8;        char *theprompt = malloc(size);        assert(theprompt);        fflush(stdout);        if ( deft != 0 && deft != 1 ) {                fprintf(stderr, "Error: Parser_getbool given bad default %d\n",                        deft);                assert ( 0 );        }        sprintf(theprompt, "%s [%s]: ", prompt, (deft==0)? "N" : "Y");        do {                line = NULL;                line = readline(theprompt);                if ( line == NULL ) {                        result = deft;                        break;                }                if ( *line == '\0' ) {                        result = deft;                        break;                }                if ( *line == 'y' || *line == 'Y' ) {                        result = 1;                        break;                }                if ( *line == 'n' || *line == 'N' ) {                        result = 0;                        break;                }                if ( line )                        free(line);                fprintf(stdout, "Invalid string. Must start with yY or nN\n");                fflush(stdout);        } while ( 1 );        if ( line )                free(line);        if ( theprompt )                free(theprompt);        return result;}/* parse int out of a string or prompt for it */long Parser_intarg(const char *inp, const char *prompt, int deft,                   int min, int max, int base){        long result;        int rc;        rc = Parser_arg2int(inp, &result, base);        if ( rc == 0 ) {                return result;        } else {                return Parser_getint(prompt, deft, min, max, base);        }}/* parse int out of a string or prompt for it */char *Parser_strarg(char *inp, const char *prompt, const char *deft,                    char *answer, int len){        if ( inp == NULL || *inp == '\0' ) {                return Parser_getstr(prompt, deft, answer, len);        } else                return inp;}/* change a string into a number: return 0 on success. No invalid characters   allowed. The processing of base and validity follows strtol(3)*/int Parser_arg2int(const char *inp, long *result, int base){        char *endptr;        if ( (base !=0) && (base < 2 || base > 36) )                return 1;        *result = strtol(inp, &endptr, base);        if ( *inp != '\0' && *endptr == '\0' )                return 0;        else                return 1;}/* Convert human readable size string to and int; "1k" -> 1000 */int Parser_size (int *sizep, char *str) {        int size;        char mod[32];        switch (sscanf (str, "%d%1[gGmMkK]", &size, mod)) {        default:                return (-1);        case 1:                *sizep = size;                return (0);        case 2:                switch (*mod) {                case 'g':                case 'G':                        *sizep = size << 30;                        return (0);                case 'm':                case 'M':                        *sizep = size << 20;                        return (0);                case 'k':                case 'K':                        *sizep = size << 10;                        return (0);                default:                        *sizep = size;                        return (0);                }        }}/* Convert a string boolean to an int; "enable" -> 1 */int Parser_bool (int *b, char *str) {        if (!strcasecmp (str, "no") ||            !strcasecmp (str, "n") ||            !strcasecmp (str, "off") ||            !strcasecmp (str, "down") ||            !strcasecmp (str, "disable"))        {                *b = 0;                return (0);        }        if (!strcasecmp (str, "yes") ||            !strcasecmp (str, "y") ||            !strcasecmp (str, "on") ||            !strcasecmp (str, "up") ||            !strcasecmp (str, "enable"))        {                *b = 1;                return (0);        }        return (-1);}int Parser_quit(int argc, char **argv){        argc = argc;        argv = argv;        done = 1;        return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?