Add a NOMATCH file

This commit is contained in:
Jay Bosamiya 2020-04-26 14:33:58 -04:00
parent 8f3d99dbb2
commit e2fac122e4
2 changed files with 40 additions and 29 deletions

View File

@ -170,8 +170,7 @@ pub fn generate_dir_short(letter: u8, target: UFat) -> Vec<u8> {
dir_entry dir_entry
} }
pub fn generate_match(target: UFat) -> Vec<u8> { pub fn generate_file(name_8_3: [u8; 11], target: UFat) -> Vec<u8> {
let name_8_3 = *b"MATCH ";
let mut dir_entry = ENTRY_TEMPLATE.to_vec(); let mut dir_entry = ENTRY_TEMPLATE.to_vec();
for (x, &y) in dir_entry.iter_mut().take(11).zip(name_8_3.iter()) { for (x, &y) in dir_entry.iter_mut().take(11).zip(name_8_3.iter()) {
*x = y; *x = y;

View File

@ -19,8 +19,9 @@ const FORBIDDEN_PRINT_ASCII: [u8; 17] = [
fn determine_state_positions<D: DFA>( fn determine_state_positions<D: DFA>(
dfa: &D, dfa: &D,
validlist: &[u8], validlist: &[u8],
nomatch: bool,
) -> Result<StateFatMap<D>, &'static str> { ) -> Result<StateFatMap<D>, &'static str> {
let nomatch_len = validlist.len() * 32; let nomatch_len = (validlist.len() + if nomatch { 1 } else { 0 }) * 32;
let match_len = (validlist.len() + 1) * 32; let match_len = (validlist.len() + 1) * 32;
// root directory starts at 2 // root directory starts at 2
let mut current_block: UFat = 2; let mut current_block: UFat = 2;
@ -73,8 +74,9 @@ fn regex_to_fat32<D: DFA, W: Write>(
dfa: &D, dfa: &D,
validlist: &[u8], validlist: &[u8],
mut vol: W, mut vol: W,
nomatch: bool,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let state_blocks = determine_state_positions(&dfa, &validlist)?; let state_blocks = determine_state_positions(&dfa, &validlist, nomatch)?;
// pad until at least 65536 blocks, since otherwise ideologically // pad until at least 65536 blocks, since otherwise ideologically
// I would have to implement fat12/fat16 // I would have to implement fat12/fat16
// also keep at least one free block for match file (which is 0 bytes, // also keep at least one free block for match file (which is 0 bytes,
@ -93,7 +95,9 @@ fn regex_to_fat32<D: DFA, W: Write>(
} }
// if accepting state, put match file into dir // if accepting state, put match file into dir
if dfa.is_match_state(state) { if dfa.is_match_state(state) {
current_dir.append(&mut fat32::generate_match(state_blocks.blocks + 2)) current_dir.append(&mut fat32::generate_file(*b"MATCH ", state_blocks.blocks + 2))
} else if nomatch {
current_dir.append(&mut fat32::generate_file(*b"NOMATCH ", state_blocks.blocks + 2))
} }
if current_dir.len() % fat32::BLOCK_SIZE == 0 { if current_dir.len() % fat32::BLOCK_SIZE == 0 {
vol.write_all(&current_dir)?; vol.write_all(&current_dir)?;
@ -114,29 +118,36 @@ fn regex_to_fat32<D: DFA, W: Write>(
} }
fn main() { fn main() {
let matches = App::new("regex2fat") let matches =
.version("0.1.0") App::new("regex2fat")
.author("8051Enthusiast") .version("0.1.0")
.about("Convert regex DFAs to FAT32 file systems") .author("8051Enthusiast")
.arg( .about("Convert regex DFAs to FAT32 file systems")
Arg::with_name("anchor") .arg(
.short("a") Arg::with_name("anchor")
.long("anchor") .short("a")
.help("Anchor regex at beginning (off by default)"), .long("anchor")
) .help("Anchor regex at beginning (off by default)"),
.arg( )
Arg::with_name("pattern") .arg(
.required(true) Arg::with_name("pattern")
.index(1) .required(true)
.help("The regex pattern to match"), .index(1)
) .help("The regex pattern to match"),
.arg( )
Arg::with_name("outfile") .arg(
.required(true) Arg::with_name("outfile")
.index(2) .required(true)
.help("The file to write the fat fs to"), .index(2)
) .help("The file to write the fat fs to"),
.get_matches(); )
.arg(
Arg::with_name("nomatch")
.short("n")
.long("nomatch")
.help("Generate NOMATCH files (off by default)"),
)
.get_matches();
let pattern = matches.value_of("pattern").unwrap(); let pattern = matches.value_of("pattern").unwrap();
let dfa = dense::Builder::new() let dfa = dense::Builder::new()
// fat32 is case insensitive // fat32 is case insensitive
@ -156,7 +167,8 @@ fn main() {
eprintln!("Could not open file '{}': {}", outfile, err); eprintln!("Could not open file '{}': {}", outfile, err);
exit(1); exit(1);
}); });
regex_to_fat32(&dfa, &validlist, file).unwrap_or_else(|err| { let nomatch = matches.is_present("nomatch");
regex_to_fat32(&dfa, &validlist, file, nomatch).unwrap_or_else(|err| {
eprintln!("Could not write DFA to '{}': {}", outfile, err); eprintln!("Could not write DFA to '{}': {}", outfile, err);
exit(1); exit(1);
}); });