parser.c

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

C
643
字号
                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);                        /* reset optind to 0 to tell getopt                         * to reinitialize itself */                        optind = 0;                }                                free(line);        }        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;}int Parser_quit(int argc, char **argv){        argc = argc;        argv = argv;        done = 1;        return 0;}

⌨️ 快捷键说明

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