?? monitor.c
字號:
if (*p == '\"') { p++; while (*p != '\0' && *p != '\"') { if (*p == '\\') { p++; c = *p++; switch(c) { case 'n': c = '\n'; break; case 'r': c = '\r'; break; case '\\': case '\'': case '\"': break; default: qemu_printf("unsupported escape code: '\\%c'\n", c); goto fail; } if ((q - buf) < buf_size - 1) { *q++ = c; } } else { if ((q - buf) < buf_size - 1) { *q++ = *p; } p++; } } if (*p != '\"') { qemu_printf("unterminated string\n"); goto fail; } p++; } else { while (*p != '\0' && !isspace(*p)) { if ((q - buf) < buf_size - 1) { *q++ = *p; } p++; } } *q = '\0'; *pp = p; return 0;}static int default_fmt_format = 'x';static int default_fmt_size = 4;#define MAX_ARGS 16static void monitor_handle_command(const char *cmdline){ const char *p, *pstart, *typestr; char *q; int c, nb_args, len, i, has_arg; term_cmd_t *cmd; char cmdname[256]; char buf[1024]; void *str_allocated[MAX_ARGS]; void *args[MAX_ARGS];#ifdef DEBUG term_printf("command='%s'\n", cmdline);#endif /* extract the command name */ p = cmdline; q = cmdname; while (isspace(*p)) p++; if (*p == '\0') return; pstart = p; while (*p != '\0' && *p != '/' && !isspace(*p)) p++; len = p - pstart; if (len > sizeof(cmdname) - 1) len = sizeof(cmdname) - 1; memcpy(cmdname, pstart, len); cmdname[len] = '\0'; /* find the command */ for(cmd = term_cmds; cmd->name != NULL; cmd++) { if (compare_cmd(cmdname, cmd->name)) goto found; } term_printf("unknown command: '%s'\n", cmdname); return; found: for(i = 0; i < MAX_ARGS; i++) str_allocated[i] = NULL; /* parse the parameters */ typestr = cmd->args_type; nb_args = 0; for(;;) { c = *typestr; if (c == '\0') break; typestr++; switch(c) { case 'F': case 'B': case 's': { int ret; char *str; while (isspace(*p)) p++; if (*typestr == '?') { typestr++; if (*p == '\0') { /* no optional string: NULL argument */ str = NULL; goto add_str; } } ret = get_str(buf, sizeof(buf), &p); if (ret < 0) { switch(c) { case 'F': term_printf("%s: filename expected\n", cmdname); break; case 'B': term_printf("%s: block device name expected\n", cmdname); break; default: term_printf("%s: string expected\n", cmdname); break; } goto fail; } str = qemu_malloc(strlen(buf) + 1); strcpy(str, buf); str_allocated[nb_args] = str; add_str: if (nb_args >= MAX_ARGS) { error_args: term_printf("%s: too many arguments\n", cmdname); goto fail; } args[nb_args++] = str; } break; case '/': { int count, format, size; while (isspace(*p)) p++; if (*p == '/') { /* format found */ p++; count = 1; if (isdigit(*p)) { count = 0; while (isdigit(*p)) { count = count * 10 + (*p - '0'); p++; } } size = -1; format = -1; for(;;) { switch(*p) { case 'o': case 'd': case 'u': case 'x': case 'i': case 'c': format = *p++; break; case 'b': size = 1; p++; break; case 'h': size = 2; p++; break; case 'w': size = 4; p++; break; case 'g': case 'L': size = 8; p++; break; default: goto next; } } next: if (*p != '\0' && !isspace(*p)) { term_printf("invalid char in format: '%c'\n", *p); goto fail; } if (format < 0) format = default_fmt_format; if (format != 'i') { /* for 'i', not specifying a size gives -1 as size */ if (size < 0) size = default_fmt_size; } default_fmt_size = size; default_fmt_format = format; } else { count = 1; format = default_fmt_format; if (format != 'i') { size = default_fmt_size; } else { size = -1; } } if (nb_args + 3 > MAX_ARGS) goto error_args; args[nb_args++] = (void*)(long)count; args[nb_args++] = (void*)(long)format; args[nb_args++] = (void*)(long)size; } break; case 'i': case 'l': { int64_t val; while (isspace(*p)) p++; if (*typestr == '?' || *typestr == '.') { if (*typestr == '?') { if (*p == '\0') has_arg = 0; else has_arg = 1; } else { if (*p == '.') { p++; while (isspace(*p)) p++; has_arg = 1; } else { has_arg = 0; } } typestr++; if (nb_args >= MAX_ARGS) goto error_args; args[nb_args++] = (void *)(long)has_arg; if (!has_arg) { if (nb_args >= MAX_ARGS) goto error_args; val = -1; goto add_num; } } if (get_expr(&val, &p)) goto fail; add_num: if (c == 'i') { if (nb_args >= MAX_ARGS) goto error_args; args[nb_args++] = (void *)(long)val; } else { if ((nb_args + 1) >= MAX_ARGS) goto error_args;#if TARGET_PHYS_ADDR_BITS > 32 args[nb_args++] = (void *)(long)((val >> 32) & 0xffffffff);#else args[nb_args++] = (void *)0;#endif args[nb_args++] = (void *)(long)(val & 0xffffffff); } } break; case '-': { int has_option; /* option */ c = *typestr++; if (c == '\0') goto bad_type; while (isspace(*p)) p++; has_option = 0; if (*p == '-') { p++; if (*p != c) { term_printf("%s: unsupported option -%c\n", cmdname, *p); goto fail; } p++; has_option = 1; } if (nb_args >= MAX_ARGS) goto error_args; args[nb_args++] = (void *)(long)has_option; } break; default: bad_type: term_printf("%s: unknown type '%c'\n", cmdname, c); goto fail; } } /* check that all arguments were parsed */ while (isspace(*p)) p++; if (*p != '\0') { term_printf("%s: extraneous characters at the end of line\n", cmdname); goto fail; } switch(nb_args) { case 0: cmd->handler(); break; case 1: cmd->handler(args[0]); break; case 2: cmd->handler(args[0], args[1]); break; case 3: cmd->handler(args[0], args[1], args[2]); break; case 4: cmd->handler(args[0], args[1], args[2], args[3]); break; case 5: cmd->handler(args[0], args[1], args[2], args[3], args[4]); break; case 6: cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]); break; case 7: cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); break; default: term_printf("unsupported number of arguments: %d\n", nb_args); goto fail; } fail: for(i = 0; i < MAX_ARGS; i++) qemu_free(str_allocated[i]); return;}static void cmd_completion(const char *name, const char *list){ const char *p, *pstart; char cmd[128]; int len; p = list; for(;;) { pstart = p; p = strchr(p, '|'); if (!p) p = pstart + strlen(pstart); len = p - pstart; if (len > sizeof(cmd) - 2) len = sizeof(cmd) - 2; memcpy(cmd, pstart, len); cmd[len] = '\0'; if (name[0] == '\0' || !strncmp(name, cmd, strlen(name))) { add_completion(cmd); } if (*p == '\0') break; p++; }}static void file_completion(const char *input){ DIR *ffs; struct dirent *d; char path[1024]; char file[1024], file_prefix[1024]; int input_path_len; const char *p; p = strrchr(input, '/'); if (!p) { input_path_len = 0; pstrcpy(file_prefix, sizeof(file_prefix), input); strcpy(path, "."); } else { input_path_len = p - input + 1; memcpy(path, input, input_path_len); if (input_path_len > sizeof(path) - 1) input_path_len = sizeof(path) - 1; path[input_path_len] = '\0'; pstrcpy(file_prefix, sizeof(file_prefix), p + 1); }#ifdef DEBUG_COMPLETION term_printf("input='%s' path='%s' prefix='%s'\n", input, path, file_prefix);#endif ffs = opendir(path); if (!ffs) return; for(;;) { struct stat sb; d = readdir(ffs); if (!d) break; if (strstart(d->d_name, file_prefix, NULL)) { memcpy(file, input, input_path_len); strcpy(file + input_path_len, d->d_name); /* stat the file to find out if it's a directory. * In that case add a slash to speed up typing long paths */ stat(file, &sb); if(S_ISDIR(sb.st_mode)) strcat(file, "/"); add_completion(file); } } closedir(ffs);}static void block_completion_it(void *opaque, const char *name){ const char *input = opaque; if (input[0] == '\0' || !strncmp(name, (char *)input, strlen(input))) { add_completion(name); }}/* NOTE: this parser is an approximate form of the real command parser */static void parse_cmdline(const char *cmdline, int *pnb_args, char **args){ const char *p; int nb_args, ret; char buf[1024]; p = cmdline; nb_args = 0; for(;;) { while (isspace(*p)) p++; if (*p == '\0') break; if (nb_args >= MAX_ARGS) break; ret = get_str(buf, sizeof(buf), &p); args[nb_args] = qemu_strdup(buf); nb_args++; if (ret < 0) break; } *pnb_args = nb_args;}void readline_find_completion(const char *cmdline){ const char *cmdname; char *args[MAX_ARGS]; int nb_args, i, len; const char *ptype, *str; term_cmd_t *cmd; const KeyDef *key; parse_cmdline(cmdline, &nb_args, args);#ifdef DEBUG_COMPLETION for(i = 0; i < nb_args; i++) { term_printf("arg%d = '%s'\n", i, (char *)args[i]); }#endif /* if the line ends with a space, it means we want to complete the next arg */ len = strlen(cmdline); if (len > 0 && isspace(cmdline[len - 1])) { if (nb_args >= MAX_ARGS) return; args[nb_args++] = qemu_strdup(""); } if (nb_args <= 1
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -