parse.c
来自「开放源码实时操作系统源码.」· C语言 代码 · 共 492 行 · 第 1/2 页
C
492 行
result = -1;
else
(cmd->fun)(argc, argv);
redboot_exec_call = false;
#ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
__mem_fault_handler = 0;
#endif
}
else
result = -1;
va_end(ap);
return result;
}
externC void err_printf( char *fmt, ... )
{
va_list ap;
va_start(ap, fmt);
diag_vprintf( fmt, ap );
va_end(ap);
// If we are not in redboot_exec() just return as usual. If we are
// inside a call to redboot_exec(), longjump out to terminate the command.
if( redboot_exec_call )
{
diag_printf("err_printf: aborting command\n");
hal_longjmp(error_jmpbuf, 1);
}
}
// Option processing
// Initialize option table entry (required because these entries
// may have dynamic contents, thus cannot be statically initialized)
//
void
init_opts(struct option_info *opts, char flag, bool takes_arg,
int arg_type, void *arg, bool *arg_set, char *name)
{
opts->flag = flag;
opts->takes_arg = takes_arg;
opts->arg_type = arg_type,
opts->arg = arg;
opts->arg_set = arg_set;
opts->name = name;
}
//
// Scan command line arguments (argc/argv), processing options, etc.
//
bool
scan_opts(int argc, char *argv[], int first,
struct option_info *opts, int num_opts,
void *def_arg, int def_arg_type, char *def_descr)
{
bool ret = true;
bool flag_ok;
bool def_arg_set = false;
int i, j;
char c, *s;
struct option_info *opt;
if (def_arg && (def_arg_type == OPTION_ARG_TYPE_STR)) {
*(char **)def_arg = (char *)0;
}
opt = opts;
for (j = 0; j < num_opts; j++, opt++) {
if (opt->arg_set) {
*opt->arg_set = false;
}
if (!opt->takes_arg) {
switch (opt->arg_type) {
case OPTION_ARG_TYPE_NUM:
*(int *)opt->arg = 0;
break;
case OPTION_ARG_TYPE_FLG:
*(bool *)opt->arg = false;
break;
}
}
}
for (i = first; i < argc; i++) {
if (argv[i][0] == '-') {
c = argv[i][1];
flag_ok = false;
opt = opts;
for (j = 0; j < num_opts; j++, opt++) {
if (c == opt->flag) {
if (opt->arg_set && *opt->arg_set) {
diag_printf("** Error: %s already specified\n", opt->name);
ret = false;
}
if (opt->takes_arg) {
if (argv[i][2] == '=') {
s = &argv[i][3];
} else {
s = argv[i+1];
i++;
}
switch (opt->arg_type) {
case OPTION_ARG_TYPE_NUM:
if (!parse_num(s, (unsigned long *)opt->arg, 0, 0)) {
diag_printf("** Error: invalid number '%s' for %s\n",
s, opt->name);
ret = false;
}
break;
case OPTION_ARG_TYPE_STR:
*(char **)opt->arg = s;
break;
}
*opt->arg_set = true;
} else {
switch (opt->arg_type) {
case OPTION_ARG_TYPE_NUM:
*(int *)opt->arg = *(int *)opt->arg + 1;
break;
case OPTION_ARG_TYPE_FLG:
*(bool *)opt->arg = true;
break;
}
}
flag_ok = true;
break;
}
}
if (!flag_ok) {
diag_printf("** Error: invalid flag '%c'\n", c);
ret = false;
}
} else {
if (def_arg) {
if (def_arg_set) {
diag_printf("** Error: %s already specified\n", def_descr);
ret = false;
}
switch (def_arg_type) {
case OPTION_ARG_TYPE_NUM:
if (!parse_num(argv[i], (unsigned long *)def_arg, 0, 0)) {
diag_printf("** Error: invalid number '%s' for %s\n",
argv[i], def_descr);
ret = false;
}
break;
case OPTION_ARG_TYPE_STR:
*(char **)def_arg = argv[i];
break;
}
def_arg_set = true;
} else {
diag_printf("** Error: no default/non-flag arguments supported\n");
ret = false;
}
}
}
return ret;
}
//
// Parse (scan) a number
//
bool
parse_num(char *s, unsigned long *val, char **es, char *delim)
{
bool first = true;
int radix = 10;
char c;
unsigned long result = 0;
int digit;
while (*s == ' ') s++;
while (*s) {
if (first && (s[0] == '0') && (_tolower(s[1]) == 'x')) {
radix = 16;
s += 2;
}
first = false;
c = *s++;
if (_is_hex(c) && ((digit = _from_hex(c)) < radix)) {
// Valid digit
#ifdef CYGPKG_HAL_MIPS
// FIXME: tx49 compiler generates 0x2539018 for MUL which
// isn't any good.
if (16 == radix)
result = result << 4;
else
result = 10 * result;
result += digit;
#else
result = (result * radix) + digit;
#endif
} else {
if (delim != (char *)0) {
// See if this character is one of the delimiters
char *dp = delim;
while (*dp && (c != *dp)) dp++;
if (*dp) break; // Found a good delimiter
}
return false; // Malformatted number
}
}
*val = result;
if (es != (char **)0) {
*es = s;
}
return true;
}
bool
parse_bool(char *s, bool *val)
{
while (*s == ' ') s++;
if ((*s == 't') || (*s == 'T')) {
char *p = "rue";
char *P = "RUE";
// check for (partial) rest of the word and no extra including the
// terminating zero. "tru" will match; "truef" will not.
while ( *++s ) {
if ( *p != *s && *P != *s ) return false;
p++; P++;
}
*val = true;
} else
if ((*s == 'f') || (*s == 'F')) {
char *p = "alse";
char *P = "ALSE";
while ( *++s ) {
if ( *p != *s && *P != *s ) return false;
p++; P++;
}
*val = false;
} else {
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?