]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
refactor path functions, working do_rm()
authorLeo C <erbl259-lmu@yahoo.de>
Sat, 26 May 2018 07:44:32 +0000 (09:44 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Sat, 26 May 2018 10:26:41 +0000 (12:26 +0200)
avr/cmd_fat.c

index 5acbb5522b0a98dd8733ad5cf876a4cf9bdb9df5..b33e27edd66886c68992898ffa3d3e2bfbc270cf 100644 (file)
@@ -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 : "<NULL>", pattern ? pattern : "<NULL>");
 
                        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,