comparison src/th06/anm0.rs @ 694:3ff1af76e413

anm0: only use recoverable errors, no panics except for anm0 asserts.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 23 Aug 2019 02:24:08 +0200
parents 7bde50132735
children b6c351ca0a35
comparison
equal deleted inserted replaced
693:14fddc27e6f5 694:3ff1af76e413
87 fn parse_name(i: &[u8], is_present: bool) -> IResult<&[u8], String> { 87 fn parse_name(i: &[u8], is_present: bool) -> IResult<&[u8], String> {
88 if !is_present { 88 if !is_present {
89 return Ok((i, String::new())); 89 return Ok((i, String::new()));
90 } 90 }
91 let (_, slice) = take_while_m_n(0, 32, |c| c != 0)(i)?; 91 let (_, slice) = take_while_m_n(0, 32, |c| c != 0)(i)?;
92 // XXX: no unwrap! 92 let string = match String::from_utf8(slice.to_vec()) {
93 let string = String::from_utf8(slice.to_vec()).unwrap(); 93 Ok(string) => string,
94 // XXX: use a more specific error instead.
95 Err(_) => return Err(nom::Err::Failure((i, nom::error::ErrorKind::Eof)))
96 };
94 Ok((i, string)) 97 Ok((i, string))
95 } 98 }
96 99
97 fn parse_sprite(i: &[u8]) -> IResult<&[u8], Sprite> { 100 fn parse_sprite(i: &[u8]) -> IResult<&[u8], Sprite> {
98 let (i, index) = le_u32(i)?; 101 let (i, index) = le_u32(i)?;
118 $( 121 $(
119 $name($($arg_type),*) 122 $name($($arg_type),*)
120 ),* 123 ),*
121 } 124 }
122 125
123 fn parse_instruction_args(input: &[u8], opcode: u8) -> IResult<&[u8], Instruction> { 126 fn parse_instruction_args(mut i: &[u8], opcode: u8) -> IResult<&[u8], Instruction> {
124 let mut i = &input[..];
125 let instr = match opcode { 127 let instr = match opcode {
126 $( 128 $(
127 $opcode => { 129 $opcode => {
128 $( 130 $(
129 let (i2, $arg) = concat_idents!(le_, $arg_type)(i)?; 131 let (i2, $arg) = concat_idents!(le_, $arg_type)(i)?;
130 i = i2; 132 i = i2;
131 )* 133 )*
132 Instruction::$name($($arg),*) 134 Instruction::$name($($arg),*)
133 } 135 }
134 )* 136 )*
135 _ => unreachable!() 137 // XXX: use a more specific error instead.
138 _ => return Err(nom::Err::Failure((i, nom::error::ErrorKind::Eof)))
136 }; 139 };
137 Ok((i, instr)) 140 Ok((i, instr))
138 } 141 }
139 }; 142 };
140 } 143 }
211 let (i2, offset) = le_u32(i2)?; 214 let (i2, offset) = le_u32(i2)?;
212 script_offsets.push((index as u8, offset as usize)); 215 script_offsets.push((index as u8, offset as usize));
213 i = i2; 216 i = i2;
214 } 217 }
215 218
219 if input.len() < start_offset + first_name_offset as usize {
220 return Err(nom::Err::Failure((input, nom::error::ErrorKind::Eof)));
221 }
216 let i = &input[start_offset + first_name_offset as usize..]; 222 let i = &input[start_offset + first_name_offset as usize..];
217 let (_, first_name) = parse_name(i, first_name_offset > 0)?; 223 let (_, first_name) = parse_name(i, first_name_offset > 0)?;
218 224
225 if input.len() < start_offset + second_name_offset as usize {
226 return Err(nom::Err::Failure((input, nom::error::ErrorKind::Eof)));
227 }
219 let i = &input[start_offset + second_name_offset as usize..]; 228 let i = &input[start_offset + second_name_offset as usize..];
220 let (_, second_name) = parse_name(i, second_name_offset > 0)?; 229 let (_, second_name) = parse_name(i, second_name_offset > 0)?;
221 230
222 let mut sprites = vec![]; 231 let mut sprites = vec![];
223 let mut i; 232 let mut i;
224 for offset in sprite_offsets { 233 for offset in sprite_offsets {
234 if input.len() < start_offset + offset {
235 return Err(nom::Err::Failure((input, nom::error::ErrorKind::Eof)));
236 }
225 i = &input[start_offset + offset..]; 237 i = &input[start_offset + offset..];
226 let (_, sprite) = parse_sprite(i)?; 238 let (_, sprite) = parse_sprite(i)?;
227 sprites.push(sprite); 239 sprites.push(sprite);
228 } 240 }
229 241
230 let mut scripts = HashMap::new(); 242 let mut scripts = HashMap::new();
231 for (index, offset) in script_offsets { 243 for (index, offset) in script_offsets {
244 if input.len() < start_offset + offset {
245 return Err(nom::Err::Failure((input, nom::error::ErrorKind::Eof)));
246 }
232 i = &input[start_offset + offset..]; 247 i = &input[start_offset + offset..];
233 let mut instruction_offsets = vec![]; 248 let mut instruction_offsets = vec![];
234 249
235 let mut instructions = vec![]; 250 let mut instructions = vec![];
236 loop { 251 loop {
253 match instr { 268 match instr {
254 Instruction::Jump(ref mut offset) => { 269 Instruction::Jump(ref mut offset) => {
255 let result = instruction_offsets.binary_search(&(*offset as usize)); 270 let result = instruction_offsets.binary_search(&(*offset as usize));
256 match result { 271 match result {
257 Ok(ptr) => *offset = ptr as u32, 272 Ok(ptr) => *offset = ptr as u32,
258 // TODO: make that a recoverable error instead. 273 Err(ptr) => {
259 Err(ptr) => panic!("Instruction offset not found for pointer: {}", ptr), 274 // XXX: use a more specific error instead.
275 return Err(nom::Err::Failure((input, nom::error::ErrorKind::Eof)));
276 //println!("Instruction offset not found for pointer: {}", ptr);
277 }
260 } 278 }
261 } 279 }
262 Instruction::InterruptLabel(interrupt) => { 280 Instruction::InterruptLabel(interrupt) => {
263 interrupts.insert(*interrupt, j + 1); 281 interrupts.insert(*interrupt, j + 1);
264 } 282 }