Skip to content

Commit 69c48fd

Browse files
thejpsterjonathanpallant
authored andcommitted
Add tree command.
1 parent d68a73f commit 69c48fd

File tree

1 file changed

+56
-1
lines changed

1 file changed

+56
-1
lines changed

examples/shell.rs

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,9 @@
7171
7272
use std::io::prelude::*;
7373

74-
use embedded_sdmmc::{Error as EsError, RawDirectory, RawVolume, VolumeIdx, VolumeManager};
74+
use embedded_sdmmc::{
75+
Error as EsError, RawDirectory, RawVolume, ShortFileName, VolumeIdx, VolumeManager,
76+
};
7577

7678
use crate::linux::{Clock, LinuxBlockDevice};
7779

@@ -200,6 +202,7 @@ impl Context {
200202
println!("\t<volume>: -> change volume/partition");
201203
println!("\tstat -> print volume manager status");
202204
println!("\tdir [<path>] -> do a directory listing");
205+
println!("\ttree [<path>] -> do a recursive directory listing");
203206
println!("\tcd .. -> go up a level");
204207
println!("\tcd <path> -> change into directory <path>");
205208
println!("\tcat <path> -> print a text file");
@@ -235,6 +238,54 @@ impl Context {
235238
Ok(())
236239
}
237240

241+
/// Print a recursive directory listing for the given path
242+
fn tree(&mut self, path: &Path) -> Result<(), Error> {
243+
println!("Directory listing of {:?}", path);
244+
let dir = self.resolve_existing_directory(path)?;
245+
// tree_dir will close this directory, always
246+
self.tree_dir(dir)
247+
}
248+
249+
/// Print a recursive directory listing for the given open directory.
250+
///
251+
/// Will close the given directory.
252+
fn tree_dir(&mut self, dir: RawDirectory) -> Result<(), Error> {
253+
let mut dir = dir.to_directory(&mut self.volume_mgr);
254+
let mut children = Vec::new();
255+
dir.iterate_dir(|entry| {
256+
println!(
257+
"{:12} {:9} {} {} {:08X?} {:?}",
258+
entry.name, entry.size, entry.ctime, entry.mtime, entry.cluster, entry.attributes
259+
);
260+
if entry.attributes.is_directory()
261+
&& entry.name != ShortFileName::this_dir()
262+
&& entry.name != ShortFileName::parent_dir()
263+
{
264+
children.push(entry.name.clone());
265+
}
266+
})?;
267+
// Be sure to close this, no matter what happens
268+
let dir = dir.to_raw_directory();
269+
for child in children {
270+
println!("Entering {}", child);
271+
let child_dir = match self.volume_mgr.open_dir(dir, &child) {
272+
Ok(child_dir) => child_dir,
273+
Err(e) => {
274+
self.volume_mgr.close_dir(dir).expect("close open dir");
275+
return Err(e);
276+
}
277+
};
278+
let result = self.tree_dir(child_dir);
279+
println!("Returning from {}", child);
280+
if let Err(e) = result {
281+
self.volume_mgr.close_dir(dir).expect("close open dir");
282+
return Err(e);
283+
}
284+
}
285+
self.volume_mgr.close_dir(dir).expect("close open dir");
286+
Ok(())
287+
}
288+
238289
/// Change into `<dir>`
239290
///
240291
/// * An arg of `..` goes up one level
@@ -346,6 +397,10 @@ impl Context {
346397
self.dir(Path::new("."))?;
347398
} else if let Some(path) = line.strip_prefix("dir ") {
348399
self.dir(Path::new(path.trim()))?;
400+
} else if line == "tree" {
401+
self.tree(Path::new("."))?;
402+
} else if let Some(path) = line.strip_prefix("tree ") {
403+
self.tree(Path::new(path.trim()))?;
349404
} else if line == "stat" {
350405
self.stat()?;
351406
} else if let Some(path) = line.strip_prefix("cd ") {

0 commit comments

Comments
 (0)