* Dive to the given DOS 8.3 file path, with optional echo of the dive paths. * * On entry: * - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...) * * On exit: * - Your curDir pointer contains an MediaFile reference to the file's directory. * - If update_cwd was 'true' the workDir now points to the file's directory. * * Returns a pointer t
| 1163 | * returned filename will be blank (points to the end of the path). |
| 1164 | */ |
| 1165 | const char* CardReader::diveToFile(const bool update_cwd, MediaFile* &inDirPtr, const char * const path, const bool echo/*=false*/) { |
| 1166 | DEBUG_SECTION(est, "diveToFile", true); |
| 1167 | |
| 1168 | // Track both parent and subfolder |
| 1169 | static MediaFile newDir1, newDir2; |
| 1170 | MediaFile *sub = &newDir1, *startDirPtr; |
| 1171 | |
| 1172 | // Parsing the path string |
| 1173 | const char *atom_ptr = path; |
| 1174 | |
| 1175 | DEBUG_ECHOLNPGM(" path = '", path, "'"); |
| 1176 | |
| 1177 | if (path[0] == '/') { // Starting at the root directory? |
| 1178 | inDirPtr = &root; |
| 1179 | atom_ptr++; |
| 1180 | DEBUG_ECHOLNPGM(" CWD to root: ", hex_address(inDirPtr)); |
| 1181 | if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs |
| 1182 | } |
| 1183 | else |
| 1184 | inDirPtr = &workDir; // Dive from workDir (as set by the UI) |
| 1185 | |
| 1186 | startDirPtr = inDirPtr; |
| 1187 | |
| 1188 | DEBUG_ECHOLNPGM(" startDirPtr = ", hex_address(startDirPtr)); |
| 1189 | |
| 1190 | while (atom_ptr) { |
| 1191 | // Find next subdirectory delimiter |
| 1192 | const char * const name_end = strchr(atom_ptr, '/'); |
| 1193 | |
| 1194 | // Last atom in the path? Item found. |
| 1195 | if (name_end <= atom_ptr) break; |
| 1196 | |
| 1197 | // Isolate the next subitem name |
| 1198 | const uint8_t len = name_end - atom_ptr; |
| 1199 | char dosSubdirname[len + 1]; |
| 1200 | strlcpy(dosSubdirname, atom_ptr, len + 1); |
| 1201 | |
| 1202 | if (echo) SERIAL_ECHOLN(dosSubdirname); |
| 1203 | |
| 1204 | DEBUG_ECHOLNPGM(" sub = ", hex_address(sub)); |
| 1205 | |
| 1206 | // Open inDirPtr (closing first) |
| 1207 | sub->close(); |
| 1208 | if (!sub->open(inDirPtr, dosSubdirname, O_READ)) { |
| 1209 | openFailed(dosSubdirname); |
| 1210 | atom_ptr = nullptr; |
| 1211 | break; |
| 1212 | } |
| 1213 | |
| 1214 | // Close inDirPtr if not at starting-point |
| 1215 | if (inDirPtr != startDirPtr) { |
| 1216 | DEBUG_ECHOLNPGM(" closing inDirPtr: ", hex_address(inDirPtr)); |
| 1217 | inDirPtr->close(); |
| 1218 | } |
| 1219 | |
| 1220 | // inDirPtr now subDir |
| 1221 | inDirPtr = sub; |
| 1222 | DEBUG_ECHOLNPGM(" inDirPtr = sub: ", hex_address(inDirPtr)); |
no test coverage detected