From 5013b94fb43ed4e86efb5d1d72350537cd1a3f8f Mon Sep 17 00:00:00 2001 From: Leo C Date: Sat, 26 May 2018 09:44:32 +0200 Subject: [PATCH] refactor path functions, working do_rm() --- avr/cmd_fat.c | 118 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 25 deletions(-) diff --git a/avr/cmd_fat.c b/avr/cmd_fat.c index 5acbb55..b33e27e 100644 --- a/avr/cmd_fat.c +++ b/avr/cmd_fat.c @@ -196,14 +196,22 @@ static void path_init(void) to.p_path[0] = '\0'; to.p_end = to.p_path; } +static char *path_skip_heading(char *p) +{ + if ((p[0] & 0x38) == '0' && p[1] == ':') { + p += 2; + } + if (*p == '/') + ++p; + + return p; +} + static void strip_trailing_slash(PATH_T *p) { - char *beg = p->p_path; + char *beg = path_skip_heading(p->p_path); char *end = p->p_end; - if ((beg + 2) < end && (*beg & 0x38) == '0' && *(beg+1) == ':') - beg += 2; - if (beg < end && *beg == '/') - ++beg; + while (end > beg && end[-1] == '/') *--end = '\0'; @@ -310,6 +318,49 @@ char *path_basename_pattern(PATH_T *p) return pattern; } +/* + * Split path + * Return basename/pattern of path. + */ + +static char *path_split_pattern(PATH_T *p) +{ + char *pp = path_skip_heading(p->p_path); + char *pattern = strrchr(pp, '/'); + + if (pattern == NULL) { + pattern = pp; + p->p_end = pattern; + } else { + p->p_end = pattern; + pattern++; + } + memmove(pattern+2, pattern, strlen(pattern)+1); + pattern += 2; + *p->p_end = '\0' ; + + return pattern; +} + +static void path_fix(PATH_T *p) +{ + char *pp = path_skip_heading(p->p_path); + + if (pp != p->p_end) { + *p->p_end++ = '/'; + *p->p_end = '\0' ; + } +} + +static void path_unfix(PATH_T *p) +{ + char *pp = path_skip_heading(p->p_path); + + if (pp != p->p_end) { + *--p->p_end = '\0' ; + } +} + static void swirl(void) { static const FLASH char swirlchar[] = { '-','\\','|','/' }; @@ -405,6 +456,7 @@ command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, FRESULT res; cmdname = argv[0]; + command_ret = CMD_RET_SUCCESS; /* reset getopt() */ optind = 0; @@ -427,7 +479,6 @@ command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, argc -= optind; argv += optind; - command_ret = CMD_RET_SUCCESS; if (argc < 1) { err(PSTR("missing operand")); } else { @@ -435,30 +486,41 @@ command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, if (!path_set(&from, argv[i])) { /* TODO: error out*/ } - char *pattern = path_basename_pattern(&from); + char *pattern = path_split_pattern(&from); debug_rm("==== path: '%s', pattern: '%s'\n", from.p_path ? from.p_path : "", pattern ? pattern : ""); res = f_findfirst(&Dir, &Finfo, from.p_path, pattern); debug_rm("==== findfirst %d\n", res); - while (res == FR_OK && Finfo.fname[0]) { - if (Finfo.fattrib & AM_DIR) { - err(PSTR("cannot remove '%s': Is a directory"), Finfo.fname); - } else { - if (!(flags & N_FLAG)) { - if ((res = f_unlink(Finfo.fname)) == FR_OK) { - if (flags & V_FLAG) - printf_P(PSTR("removed '%s'\n"), Finfo.fname); + + if (res != FR_OK || !Finfo.fname[0]) { + path_fix(&from); + err(PSTR("cannot remove '%s%s': No such file or directory"), from.p_path, pattern); + } else { + do { + if (Finfo.fattrib & AM_DIR) { + path_fix(&from); + err(PSTR("cannot remove '%s%s': Is a directory"), from.p_path, Finfo.fname); + } else { + if (!(flags & N_FLAG)) { + if ((res = f_unlink(Finfo.fname)) == FR_OK) { + if (flags & V_FLAG) + path_fix(&from); + printf_P(PSTR("removed '%s%s'\n"), from.p_path, Finfo.fname); + path_unfix(&from); + } else { + path_fix(&from); + err(PSTR("cannot remove '%s%s': %S"), from.p_path, Finfo.fname, rctostr(res)); + } } else { - err(PSTR("cannot remove '%s': Read only?"), Finfo.fname); - put_rc(res); + path_fix(&from); + printf_P(PSTR("not removed '%s%s'\n"), from.p_path, Finfo.fname); + path_unfix(&from); } - } else { - printf_P(PSTR("not removed '%s'\n"), Finfo.fname); } - } - res = f_findnext(&Dir, &Finfo); - debug_rm("==== findnext %d\n", res); + res = f_findnext(&Dir, &Finfo); + //debug_rm("==== findnext %d\n", res); + } while (res == FR_OK && Finfo.fname[0]); } f_closedir(&Dir); } @@ -475,15 +537,17 @@ command_ret_t do_rm(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, command_ret_t do_rmdir(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { cmdname = argv[0]; + command_ret = CMD_RET_SUCCESS; - return CMD_RET_SUCCESS; + return command_ret; } command_ret_t do_mkdir(cmd_tbl_t *cmdtp UNUSED, uint_fast8_t flag UNUSED, int argc, char * const argv[]) { cmdname = argv[0]; + command_ret = CMD_RET_SUCCESS; - return CMD_RET_SUCCESS; + return command_ret; } @@ -1218,7 +1282,11 @@ CMD_TBL_ITEM( CMD_TBL_ITEM( rm, CONFIG_SYS_MAXARGS, 0, do_rm, "Remove FILE(s)", - "[OPTION]... [FILE]..." + "[OPTION]... [FILE]...\n" + //" -i prompt before removal\n" + " -v explain what is being done\n" + "\n" + "rm does not remove directories." ), CMD_TBL_ITEM( rmdir, CONFIG_SYS_MAXARGS, 0, do_rmdir, -- 2.39.2