From: Leo C Date: Mon, 9 Apr 2018 21:51:36 +0000 (+0200) Subject: Recursive cmd_find(), new command table flag: CTBL_RPT X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/commitdiff_plain/82c475ad6fb4a6a7ab77fc05e8953401093cffca Recursive cmd_find(), new command table flag: CTBL_RPT --- diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index cd35c8a..90af1be 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -166,7 +166,7 @@ FRESULT scan_files ( * fatstat path - Show logical drive status * */ -command_ret_t do_stat(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) +command_ret_t do_stat(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { FATFS *fs; DWORD nfreeclst; @@ -175,8 +175,6 @@ command_ret_t do_stat(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons char *path = ""; struct stat_dat_s statp; - (void) cmdtp; (void) flag; (void) argc; - buf = (char *) malloc(BUFFER_SIZE); if (buf == NULL) { printf_P(PSTR("fat stat: Out of Memory!\n")); @@ -745,32 +743,32 @@ command_ret_t do_cp(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, cmd_tbl_t cmd_tbl_fat[] = { CMD_TBL_ITEM( - stat, 2, CTBL_REPEAT, do_stat, + stat, 2, CTBL_RPT, do_stat, "Show logical drive status", "dev" ), CMD_TBL_ITEM( - pwd, 2, CTBL_REPEAT, do_pwd, + pwd, 2, CTBL_RPT, do_pwd, "Print name of current/working directory", "" ), CMD_TBL_ITEM( - cd, 2, CTBL_REPEAT, do_cd, + cd, 2, 0, do_cd, "Change the current/working directory.", "path" ), CMD_TBL_ITEM( - ls, 2, CTBL_REPEAT, do_ls, + ls, 2, CTBL_RPT, do_ls, "Directory listing", "path" ), CMD_TBL_ITEM( - tst, 2, CTBL_REPEAT, do_tst, + tst, 2, CTBL_DBG|CTBL_RPT, do_tst, "FatFS test function", "path" ), CMD_TBL_ITEM( - load, 5, 0, do_rw, + load, 5, 0, do_rw, "load binary file from a dos filesystem", " [bytes [pos]]\n" " - Load binary file 'path/filename' on logical drive 'd'\n" @@ -781,7 +779,7 @@ CMD_TBL_ITEM( " the load stops on end of file." ), CMD_TBL_ITEM( - write, 4, 0, do_rw, + write, 4, 0, do_rw, "write file into a dos filesystem", " \n" " - Write file to 'path/filename' on logical drive 'd' from RAM\n" @@ -789,14 +787,14 @@ CMD_TBL_ITEM( ), CMD_TBL_ITEM( - cp, CONFIG_SYS_MAXARGS, 0, do_cp, + cp, CONFIG_SYS_MAXARGS, CTBL_DBG, do_cp, "copy files", - "cp [-R] [-f | -i | -n] [-aprv] source_file target_file\n" + "[-R] [-f | -i | -n] [-aprv] source_file target_file\n" " - \n" ), CMD_TBL_ITEM( - help, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_help, + help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help, "Print sub command description/usage", "\n" " - print brief description of all sub commands\n" diff --git a/avr/cmd_sd.c b/avr/cmd_sd.c index e2adbe7..ba4c835 100644 --- a/avr/cmd_sd.c +++ b/avr/cmd_sd.c @@ -316,43 +316,43 @@ command_ret_t do_ioctl_sync(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char cmd_tbl_t cmd_tbl_sd[] = { CMD_TBL_ITEM( - status, 2, CTBL_REPEAT, do_status, + status, 2, CTBL_RPT, do_status, "Socket staus", "drive" ), CMD_TBL_ITEM( - init, 2, CTBL_REPEAT, do_init, + init, 2, CTBL_RPT, do_init, "Initialize disk", "drive" ), CMD_TBL_ITEM( - info, 2, CTBL_REPEAT, do_info, + info, 2, CTBL_RPT, do_info, "Disk info", "drive" ), CMD_TBL_ITEM( - dump, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_dump, + dump, CONFIG_SYS_MAXARGS, CTBL_RPT, do_dump, "Dump sector(s)", "drive [sector [count ]]" ), CMD_TBL_ITEM( - read, 2, CTBL_REPEAT, do_read, + read, 2, CTBL_RPT, do_read, "Read disk sector(s) into meomory", "drive [sector [count [memaddr]]]" ), CMD_TBL_ITEM( - write, 2, CTBL_REPEAT, do_write, + write, 2, CTBL_RPT, do_write, "Write sector(s) from meomory to disk", "drive [sector [count [memaddr]]]" ), CMD_TBL_ITEM( - sync, 2, CTBL_REPEAT, do_ioctl_sync, + sync, 2, CTBL_RPT, do_ioctl_sync, "Device control: SYNC", "drive" ), CMD_TBL_ITEM( - help, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_help, + help, CONFIG_SYS_MAXARGS, CTBL_RPT, do_help, "Print sub command description/usage", "\n" " - print brief description of all sub commands\n" @@ -378,6 +378,6 @@ CMD_TBL_END(cmd_tbl_sd) command_ret_t do_sd(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) { - puts_P("Huch?"); + puts_P(PSTR("Huch?")); return CMD_RET_USAGE; } diff --git a/avr/command.c b/avr/command.c index aa784cb..e88e2f3 100644 --- a/avr/command.c +++ b/avr/command.c @@ -85,47 +85,69 @@ cmd_tbl_t *get_cmd_tbl_base(cmd_tbl_t *cmdtp) /* * find command table entry for a command */ -cmd_tbl_t *find_cmd (const char *cmd, cmd_tbl_t *table) -{ - cmd_tbl_t *cmdtp; - cmd_tbl_t *cmdtp_temp = table; /*Init value */ - int table_len = cmd_tbl_item_count(table); - size_t len; - uint_fast8_t n_found = 0; - - char *optenv = getenv_str(PSTR("cmd")); - bool opt_debug = optenv && strstr_P(optenv, PSTR("debug")) != NULL; - - if (!cmd) - return NULL; +typedef struct { + size_t len; + uint_fast8_t level; + bool opt_debug; + } find_cmd_para_t; - len = strlen(cmd); +cmd_tbl_t *_find_cmd (const char *cmd, cmd_tbl_t *table, find_cmd_para_t *para) +{ + cmd_tbl_t *cmdtp_ret = NULL; + uint_fast8_t n_found = 0, sub_found = 0; - for (cmdtp = table; - cmdtp != table + table_len; - cmdtp++) { - if (strncmp_P(cmd, cmdtp->name, len) == 0 && - (opt_debug || cmdtp->name[0] != '!')) { - if (len == strlen_P(cmdtp->name)) + for (cmd_tbl_t *cmdtp = table; cmdtp->name != NULL; cmdtp++) { + if (strncmp_P(cmd, cmdtp->name, para->len) == 0 && + (para->opt_debug || !(cmdtp->flags & CTBL_DBG))) { + if (para->len == strlen_P(cmdtp->name)) return cmdtp; /* full match */ - cmdtp_temp = cmdtp; /* abbreviated command ? */ + cmdtp_ret = cmdtp; /* abbreviated command ? */ n_found++; + } else if (cmdtp->subcmd && cmdtp->flags & CTBL_SUBCMDAUTO) { + cmd_tbl_t *sub = _find_cmd(cmd, cmdtp->subcmd, para); + if (sub) { + cmdtp_ret = sub; + ++n_found; + } } } - if (n_found == 1) /* exactly one match */ - return cmdtp_temp; + if (n_found == 1) { /* exactly one match */ + if (sub_found) + para->level++; + return cmdtp_ret; + } return NULL; /* not found or ambiguous command */ } + +cmd_tbl_t *find_cmd (const char *cmd, cmd_tbl_t *table, uint_fast8_t *cmdlevel) +{ + find_cmd_para_t para; + + if (!cmd) + return NULL; + + char *optenv = getenv_str(PSTR("cmd")); + para.level = 0; + para.opt_debug = optenv && strstr_P(optenv, PSTR("debug")) != NULL; + para.len = strlen(cmd); + + cmd_tbl_t *cmdtp = _find_cmd(cmd, table, ¶); + + if (cmdlevel) + *cmdlevel = para.level; + return cmdtp; +} + cmd_tbl_t *find_cmd_sub(const char *cmd, cmd_tbl_t *table) { cmd_tbl_t *entry = NULL; for (cmd_tbl_t *tp = get_cmd_tbl_base(table); tp->name && entry == NULL; tp++) if (tp->subcmd && tp->flags & CTBL_SUBCMDAUTO) - entry = find_cmd(cmd, tp->subcmd); + entry = find_cmd(cmd, tp->subcmd, NULL); return entry; } @@ -135,10 +157,8 @@ cmd_tbl_t *find_cmd_sub(const char *cmd, cmd_tbl_t *table) * for long help messages */ -command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * const argv[]) +command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { - (void) flag; - cmd_tbl_t *tbl_start = get_cmd_tbl_base(cmdtp); char *optenv = getenv_str(PSTR("cmd")); @@ -163,7 +183,7 @@ command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons /* print short help (usage) */ for (int i = 0; i < cmd_items; i++) { - if (opt_debug || cmd_array[i]->name[0] != '!') { + if (opt_debug || !(cmd_array[i]->flags & CTBL_DBG)) { const FLASH char *usage = cmd_array[i]->usage; /* allow user abort */ @@ -186,7 +206,7 @@ command_ret_t do_help(cmd_tbl_t *cmdtp, uint_fast8_t flag, int argc, char * cons * command help (long version) */ for (uint8_t i = 1; i < argc; ++i) { - if ((cmdtp = find_cmd(argv[i], tbl_start)) != NULL && + if ((cmdtp = find_cmd(argv[i], tbl_start, NULL)) != NULL && (opt_debug || cmdtp->name[0] != '!')) { cmd_usage(cmdtp); } else { @@ -518,15 +538,16 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], { command_ret_t rc = CMD_RET_SUCCESS; cmd_tbl_t *cmdtp; + uint_fast8_t cmdlevel; /* Look up command in command table */ - cmdtp = find_cmd(argv[0], cmd_tbl); + cmdtp = find_cmd(argv[0], cmd_tbl, &cmdlevel); if (cmdtp != NULL) { /* Check if this command has subcommands */ if (cmdtp->subcmd && argc > 1) { /* Look up subcommand in subcommand table */ - cmd_tbl_t *cmdtpsub = find_cmd(argv[1], cmdtp->subcmd); + cmd_tbl_t *cmdtpsub = find_cmd(argv[1], cmdtp->subcmd, &cmdlevel); if (cmdtpsub == NULL) { printf_P(PSTR("Unknown '%s' subcommand '%s' - try '%s help'\n"), argv[0], argv[1], argv[0]); return CMD_RET_FAILURE; @@ -535,10 +556,13 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], --argc; ++argv; } - } else { + } +#if 0 + else { /* Search subcommands */ - cmdtp = find_cmd_sub(argv[0], cmd_tbl); + cmdtp = find_cmd_sub(argv[0], cmd_tbl, &cmdlevel); } +#endif if (cmdtp == NULL) { printf_P(PSTR("Unknown command '%s' - try 'help'\n"), argv[0]); @@ -567,7 +591,7 @@ command_ret_t cmd_process(uint_fast8_t flag, int argc, char * const argv[], /* If OK so far, then do the command */ if (!rc) { rc = cmd_call(cmdtp, flag, argc, argv); - *repeatable &= (cmdtp->flags & CTBL_REPEAT) != 0; + *repeatable &= (cmdtp->flags & CTBL_RPT) != 0; } if (rc == CMD_RET_USAGE) rc = cmd_usage(cmdtp); diff --git a/avr/command_tbl.c b/avr/command_tbl.c index 861e72b..1769714 100644 --- a/avr/command_tbl.c +++ b/avr/command_tbl.c @@ -34,42 +34,42 @@ CMD_TBL_ITEM( #ifdef DEBUG CMD_TBL_ITEM( - !mdr, 3, 1, do_dump_mem, + !mdr, 3, CTBL_DBG|CTBL_RPT, do_dump_mem, "RAM dump", "address [count]" ), CMD_TBL_ITEM( - !mde, 3, 1, do_dump_mem, + !mde, 3, CTBL_DBG|CTBL_RPT, do_dump_mem, "EEPROM dump", "address [count]" ), CMD_TBL_ITEM( - !mdf, 3, 1, do_dump_mem, + !mdf, 3, CTBL_DBG|CTBL_RPT, do_dump_mem, "FLASH dump", "address [count]" ), CMD_TBL_ITEM( - !cpe, 4, 0, do_eep_cp, + !cpe, 4, CTBL_DBG, do_eep_cp, "EEPROM copy", "source target count" ), CMD_TBL_ITEM( - !mm, 2, 1, do_mem_mm_avr, + !mm, 2, CTBL_DBG|CTBL_RPT, do_mem_mm_avr, "avr memory modify (auto-incrementing address)", "address" ), CMD_TBL_ITEM( - !nm, 2, 1, do_mem_nm_avr, + !nm, 2, CTBL_DBG|CTBL_RPT, do_mem_nm_avr, "avr memory modify (constant address)", "address" ), CMD_TBL_ITEM( - !prfree, 1, 1, do_pr_free_avr, + !prfree, 1, CTBL_DBG|CTBL_RPT, do_pr_free_avr, "print avr heap free list", "" ), CMD_TBL_ITEM( - !prheap, 1, 1, do_pr_heap_avr, + !prheap, 1, CTBL_DBG, do_pr_heap_avr, "dump avr heap", "" ), @@ -248,22 +248,22 @@ CMD_TBL_ITEM( ), CMD_TBL_ITEM( - md, 3, CTBL_REPEAT, do_mem_md, + md, 3, CTBL_RPT, do_mem_md, "memory display", "address [# of objects]" ), CMD_TBL_ITEM( - mm, 2, CTBL_REPEAT, do_mem_mm, + mm, 2, CTBL_RPT, do_mem_mm, "memory modify (auto-incrementing address)", "address" ), CMD_TBL_ITEM( - nm, 2, CTBL_REPEAT, do_mem_nm, + nm, 2, CTBL_RPT, do_mem_nm, "memory modify (constant address)", "address" ), CMD_TBL_ITEM( - mw, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_mem_mw, + mw, CONFIG_SYS_MAXARGS, CTBL_RPT, do_mem_mw, "memory write (fill)", "[-bwl] address value [count]\n" " -b write value as byte (8 bit, default)\n" @@ -271,12 +271,12 @@ CMD_TBL_ITEM( " -l write value as long (32 bit)" ), CMD_TBL_ITEM( - cp, 4, CTBL_REPEAT, do_mem_cp, + cp, 4, CTBL_RPT, do_mem_cp, "memory copy", "source target count" ), CMD_TBL_ITEM( - cmp, 4, CTBL_REPEAT, do_mem_cmp, + cmp, 4, CTBL_RPT, do_mem_cmp, "memory compare", "addr1 addr2 count" ), @@ -289,19 +289,19 @@ CMD_TBL_ITEM( " - set address offset for memory commands to 'offset'" ), CMD_TBL_ITEM( - mloop, 3, CTBL_REPEAT, do_mem_loop, + mloop, 3, CTBL_RPT, do_mem_loop, "infinite loop on address range", "address number_of_bytes" ), CMD_TBL_ITEM( - mloopw, 4, CTBL_REPEAT, do_mem_loopw, + mloopw, 4, CTBL_RPT, do_mem_loopw, "infinite write loop on address range", "address number_of_bytes data_to_write" ), #ifdef CONFIG_CMD_MEMTEST CMD_TBL_ITEM( - mtest, 4, CTBL_REPEAT, do_mem_mtest, + mtest, 4, CTBL_RPT, do_mem_mtest, "simple RAM read/write test", "[start [end [iterations]]]" ), @@ -309,12 +309,12 @@ CMD_TBL_ITEM( #ifdef CONFIG_MX_CYCLIC CMD_TBL_ITEM( - mdc, 4, CTBL_REPEAT, do_mem_mdc, + mdc, 4, CTBL_RPT, do_mem_mdc, "memory display cyclic", "address count delay(ms)" ), CMD_TBL_ITEM( - mwc, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_mem_mdc, + mwc, CONFIG_SYS_MAXARGS, CTBL_RPT, do_mem_mdc, "memory write cyclic", "[-bwl] address value delay(ms)\n" " -b write value as byte (8 bit, default)\n" @@ -341,7 +341,7 @@ CMD_TBL_ITEM_TOP( ), CMD_TBL_ITEM( - attach, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_attach, + attach, CONFIG_SYS_MAXARGS, CTBL_RPT, do_attach, "attach filesystem image file to CP/M drive", "[-rw] [-o options] dsk diskfile\n" " Attach diskfile to dsk, where n in 0..7\n" @@ -364,14 +364,14 @@ CMD_TBL_ITEM( " Without arguments, list current assignments" ), CMD_TBL_ITEM( - detach, 2, CTBL_REPEAT, do_attach, + detach, 2, 0, do_attach, "detach file from CP/M drive", "dsk]\n" " - alias for 'attach -d dsk'" ), CMD_TBL_ITEM( - help, CONFIG_SYS_MAXARGS, CTBL_REPEAT, do_help, + help, CONFIG_SYS_MAXARGS, 0, do_help, "print command description/usage", "\n" " - print brief description of all commands\n" diff --git a/include/command.h b/include/command.h index fb7f9b8..d7eccc9 100644 --- a/include/command.h +++ b/include/command.h @@ -133,9 +133,10 @@ extern int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, /* * Flags for command table: */ -#define CTBL_REPEAT 0x01 /* command is repeatable */ +#define CTBL_RPT 0x01 /* command is repeatable */ #define CTBL_SUBCMD 0x02 /* command has subcommands */ -#define CTBL_SUBCMDAUTO 0x04 /* execute subcommands whithout prefix*/ +#define CTBL_SUBCMDAUTO 0x04 /* execute subcommands whithout prefix */ +#define CTBL_DBG 0x08 /* command is only for debugging */ #ifdef CONFIG_AUTO_COMPLETE # define _CMD_COMPLETE(x) x,