Clean up run-emitter-test-suite implementation

This commit is contained in:
David Tolnay 2022-07-08 09:56:07 -07:00
parent 9d367c1b68
commit df24355436
No known key found for this signature in database
GPG key ID: F9BA143B95FF6D82

View file

@ -35,28 +35,22 @@ use unsafe_libyaml::{
yaml_sequence_end_event_initialize, yaml_sequence_start_event_initialize, yaml_sequence_end_event_initialize, yaml_sequence_start_event_initialize,
yaml_stream_end_event_initialize, yaml_stream_start_event_initialize, yaml_tag_directive_t, yaml_stream_end_event_initialize, yaml_stream_start_event_initialize, yaml_tag_directive_t,
yaml_version_directive_t, YAML_ANY_SCALAR_STYLE, YAML_BLOCK_MAPPING_STYLE, yaml_version_directive_t, YAML_ANY_SCALAR_STYLE, YAML_BLOCK_MAPPING_STYLE,
YAML_BLOCK_SEQUENCE_STYLE, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE, YAML_BLOCK_SEQUENCE_STYLE, YAML_DOUBLE_QUOTED_SCALAR_STYLE, YAML_EMITTER_ERROR,
YAML_LITERAL_SCALAR_STYLE, YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_FOLDED_SCALAR_STYLE, YAML_LITERAL_SCALAR_STYLE, YAML_MEMORY_ERROR,
YAML_UTF8_ENCODING, YAML_PLAIN_SCALAR_STYLE, YAML_SINGLE_QUOTED_SCALAR_STYLE, YAML_UTF8_ENCODING,
YAML_WRITER_ERROR,
}; };
pub(crate) unsafe fn unsafe_main( pub(crate) unsafe fn unsafe_main(
stdin: &mut dyn Read, stdin: &mut dyn Read,
mut stdout: &mut dyn Write, mut stdout: &mut dyn Write,
) -> Result<(), Box<dyn Error>> { ) -> Result<(), Box<dyn Error>> {
let current_block: u64;
let mut emitter = MaybeUninit::<yaml_emitter_t>::uninit(); let mut emitter = MaybeUninit::<yaml_emitter_t>::uninit();
let emitter = emitter.as_mut_ptr(); let emitter = emitter.as_mut_ptr();
let mut event = MaybeUninit::<yaml_event_t>::uninit();
let event = event.as_mut_ptr();
let version_directive: *mut yaml_version_directive_t =
ptr::null_mut::<yaml_version_directive_t>();
let canonical = 0_i32;
let unicode = 0_i32;
let mut buf = ReadBuf::new();
if yaml_emitter_initialize(emitter) == 0 { if yaml_emitter_initialize(emitter) == 0 {
return Err("Could not initalize the emitter object".into()); return Err("Could not initalize the emitter object".into());
} }
unsafe fn write_to_stdio(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 { unsafe fn write_to_stdio(data: *mut c_void, buffer: *mut u8, size: u64) -> i32 {
let stdout: *mut &mut dyn Write = data.cast(); let stdout: *mut &mut dyn Write = data.cast();
let bytes = slice::from_raw_parts(buffer.cast(), size as usize); let bytes = slice::from_raw_parts(buffer.cast(), size as usize);
@ -65,110 +59,98 @@ pub(crate) unsafe fn unsafe_main(
Err(_) => 0, Err(_) => 0,
} }
} }
yaml_emitter_set_output(emitter, Some(write_to_stdio), addr_of_mut!(stdout).cast()); yaml_emitter_set_output(emitter, Some(write_to_stdio), addr_of_mut!(stdout).cast());
yaml_emitter_set_canonical(emitter, canonical); yaml_emitter_set_canonical(emitter, 0);
yaml_emitter_set_unicode(emitter, unicode); yaml_emitter_set_unicode(emitter, 0);
loop {
let mut buf = ReadBuf::new();
let mut event = MaybeUninit::<yaml_event_t>::uninit();
let event = event.as_mut_ptr();
let result = loop {
let line = match buf.get_line(stdin) { let line = match buf.get_line(stdin) {
Some(line) => line, Some(line) => line,
None => { None => break Ok(()),
current_block = 1934991416718554651;
break;
}
}; };
let line = line as *mut [u8] as *mut i8;
let ok: i32; let mut anchor = [0u8; 256];
let mut anchor: [i8; 256] = [0; 256]; let mut tag = [0u8; 256];
let mut tag: [i8; 256] = [0; 256]; let ok = if line.starts_with(b"+STR") {
let implicit: i32; yaml_stream_start_event_initialize(event, YAML_UTF8_ENCODING)
if strncmp(line, b"+STR\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"-STR") {
ok = yaml_stream_start_event_initialize(event, YAML_UTF8_ENCODING); yaml_stream_end_event_initialize(event)
} else if strncmp(line, b"-STR\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"+DOC") {
ok = yaml_stream_end_event_initialize(event); let implicit = !line[4..].starts_with(b" ---") as i32;
} else if strncmp(line, b"+DOC\0" as *const u8 as *const i8, 4_u64) == 0_i32 { yaml_document_start_event_initialize(
implicit = (strncmp(
line.offset(4_isize),
b" ---\0" as *const u8 as *const i8,
4_u64,
) != 0_i32) as i32;
ok = yaml_document_start_event_initialize(
event, event,
version_directive, ptr::null_mut::<yaml_version_directive_t>(),
ptr::null_mut::<yaml_tag_directive_t>(), ptr::null_mut::<yaml_tag_directive_t>(),
ptr::null_mut::<yaml_tag_directive_t>(), ptr::null_mut::<yaml_tag_directive_t>(),
implicit, implicit,
); )
} else if strncmp(line, b"-DOC\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"-DOC") {
implicit = (strncmp( let implicit = !line[4..].starts_with(b" ...") as i32;
line.offset(4_isize), yaml_document_end_event_initialize(event, implicit)
b" ...\0" as *const u8 as *const i8, } else if line.starts_with(b"+MAP") {
4_u64, yaml_mapping_start_event_initialize(
) != 0_i32) as i32;
ok = yaml_document_end_event_initialize(event, implicit);
} else if strncmp(line, b"+MAP\0" as *const u8 as *const i8, 4_u64) == 0_i32 {
ok = yaml_mapping_start_event_initialize(
event, event,
get_anchor('&' as i32 as i8, line, anchor.as_mut_ptr()) as *mut u8, get_anchor(b'&', line, anchor.as_mut_ptr()),
get_tag(line, tag.as_mut_ptr()) as *mut u8, get_tag(line, tag.as_mut_ptr()),
0_i32, 0,
YAML_BLOCK_MAPPING_STYLE, YAML_BLOCK_MAPPING_STYLE,
); )
} else if strncmp(line, b"-MAP\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"-MAP") {
ok = yaml_mapping_end_event_initialize(event); yaml_mapping_end_event_initialize(event)
} else if strncmp(line, b"+SEQ\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"+SEQ") {
ok = yaml_sequence_start_event_initialize( yaml_sequence_start_event_initialize(
event, event,
get_anchor('&' as i32 as i8, line, anchor.as_mut_ptr()) as *mut u8, get_anchor(b'&', line, anchor.as_mut_ptr()),
get_tag(line, tag.as_mut_ptr()) as *mut u8, get_tag(line, tag.as_mut_ptr()),
0_i32, 0,
YAML_BLOCK_SEQUENCE_STYLE, YAML_BLOCK_SEQUENCE_STYLE,
); )
} else if strncmp(line, b"-SEQ\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"-SEQ") {
ok = yaml_sequence_end_event_initialize(event); yaml_sequence_end_event_initialize(event)
} else if strncmp(line, b"=VAL\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"=VAL") {
let mut value: [i8; 1024] = [0; 1024]; let mut value = [0i8; 1024];
let mut style = YAML_ANY_SCALAR_STYLE; let mut style = YAML_ANY_SCALAR_STYLE;
get_value(line, value.as_mut_ptr(), &mut style); get_value(line, value.as_mut_ptr(), &mut style);
implicit = let implicit = get_tag(line, tag.as_mut_ptr()).is_null() as i32;
(get_tag(line, tag.as_mut_ptr()) == ptr::null_mut::<c_void>() as *mut i8) as i32; yaml_scalar_event_initialize(
ok = yaml_scalar_event_initialize(
event, event,
get_anchor('&' as i32 as i8, line, anchor.as_mut_ptr()) as *mut u8, get_anchor(b'&', line, anchor.as_mut_ptr()),
get_tag(line, tag.as_mut_ptr()) as *mut u8, get_tag(line, tag.as_mut_ptr()),
value.as_mut_ptr() as *mut u8, value.as_mut_ptr() as *mut u8,
-1_i32, -1,
implicit, implicit,
implicit, implicit,
style, style,
); )
} else if strncmp(line, b"=ALI\0" as *const u8 as *const i8, 4_u64) == 0_i32 { } else if line.starts_with(b"=ALI") {
ok = yaml_alias_event_initialize( yaml_alias_event_initialize(event, get_anchor(b'*', line, anchor.as_mut_ptr()))
event,
get_anchor('*' as i32 as i8, line, anchor.as_mut_ptr()) as *mut u8,
);
} else { } else {
yaml_emitter_delete(emitter); let line = line as *mut [u8] as *mut i8;
return Err(format!("Unknown event: '{}'", CStr::from_ptr(line)).into()); break Err(format!("Unknown event: '{}'", CStr::from_ptr(line)).into());
} };
if ok == 0 { if ok == 0 {
current_block = 13850764817919632987; break Err("Memory error: Not enough memory for creating an event".into());
break;
} }
if yaml_emitter_emit(emitter, event) == 0 { if yaml_emitter_emit(emitter, event) == 0 {
current_block = 6684355725484023210; break Err(match (*emitter).error {
break; YAML_MEMORY_ERROR => "Memory error: Not enough memory for emitting".into(),
YAML_WRITER_ERROR => {
format!("Writer error: {}", CStr::from_ptr((*emitter).problem)).into()
}
YAML_EMITTER_ERROR => {
format!("Emitter error: {}", CStr::from_ptr((*emitter).problem)).into()
}
// Couldn't happen.
_ => "Internal error".into(),
});
} }
}
let result = match current_block {
13850764817919632987 => Err("Memory error: Not enough memory for creating an event".into()),
6684355725484023210 => Err(match (*emitter).error as u32 {
1 => "Memory error: Not enough memory for emitting".into(),
6 => format!("Writer error: {}", CStr::from_ptr((*emitter).problem)).into(),
7 => format!("Emitter error: {}", CStr::from_ptr((*emitter).problem)).into(),
_ => "Internal error".into(),
}),
_ => Ok(()),
}; };
yaml_emitter_delete(emitter); yaml_emitter_delete(emitter);
result result
} }
@ -222,168 +204,85 @@ impl ReadBuf {
} }
} }
unsafe fn get_anchor(sigil: i8, line: *mut i8, anchor: *mut i8) -> *mut i8 { unsafe fn get_anchor(sigil: u8, line: &[u8], anchor: *mut u8) -> *mut u8 {
let mut start: *mut i8; let start = match line.iter().position(|ch| *ch == sigil) {
let mut end: *mut i8; Some(offset) => offset + 1,
start = strchr(line, sigil as i32); None => return ptr::null_mut::<u8>(),
if start.is_null() { };
return ptr::null_mut::<i8>(); let end = match line[start..].iter().position(|ch| *ch == b' ') {
} Some(offset) => start + offset,
start = start.offset(1); None => line.len(),
end = strchr(start, ' ' as i32); };
if end.is_null() { ptr::copy_nonoverlapping(line[start..end].as_ptr(), anchor, end - start);
end = line.offset(strlen(line) as isize); *anchor.add(end - start) = b'\0';
}
memcpy(
anchor as *mut c_void,
start as *const c_void,
end.offset_from(start) as i64 as u64,
);
*anchor.offset(end.offset_from(start) as i64 as isize) = '\0' as i32 as i8;
anchor anchor
} }
unsafe fn get_tag(line: *mut i8, tag: *mut i8) -> *mut i8 { unsafe fn get_tag(line: &[u8], tag: *mut u8) -> *mut u8 {
let start: *mut i8 = strchr(line, '<' as i32); let start = match line.iter().position(|ch| *ch == b'<') {
if start.is_null() { Some(offset) => offset + 1,
return ptr::null_mut::<i8>(); None => return ptr::null_mut::<u8>(),
} };
let end: *mut i8 = strchr(line, '>' as i32); let end = match line[start..].iter().position(|ch| *ch == b'>') {
if end.is_null() { Some(offset) => start + offset,
return ptr::null_mut::<i8>(); None => return ptr::null_mut::<u8>(),
} };
memcpy( ptr::copy_nonoverlapping(line[start..end].as_ptr(), tag, end - start);
tag as *mut c_void, *tag.add(end - start) = b'\0';
start.offset(1_isize) as *const c_void,
(end.offset_from(start) as i64 - 1_i64) as u64,
);
*tag.offset((end.offset_from(start) as i64 - 1_i64) as isize) = '\0' as i32 as i8;
tag tag
} }
unsafe fn get_value(line: *mut i8, value: *mut i8, style: *mut yaml_scalar_style_t) { unsafe fn get_value(line: &[u8], value: *mut i8, style: *mut yaml_scalar_style_t) {
let mut i: i32 = 0_i32; let line_len = line.len();
let mut c: *mut i8; let line = line as *const [u8] as *mut i8;
let mut start: *mut i8 = ptr::null_mut::<i8>(); let mut start = ptr::null_mut::<i8>();
let end: *mut i8 = line.offset(strlen(line) as isize); let end = line.offset(line_len as isize);
let mut current_block_8: u64; let mut c = line.offset(4);
c = line.offset(4_isize);
while c < end { while c < end {
if *c as i32 == ' ' as i32 { if *c as u8 == b' ' {
start = c.offset(1_isize); start = c.offset(1);
if *start as i32 == ':' as i32 { *style = match *start as u8 {
*style = YAML_PLAIN_SCALAR_STYLE; b':' => YAML_PLAIN_SCALAR_STYLE,
current_block_8 = 17407779659766490442; b'\'' => YAML_SINGLE_QUOTED_SCALAR_STYLE,
} else if *start as i32 == '\'' as i32 { b'"' => YAML_DOUBLE_QUOTED_SCALAR_STYLE,
*style = YAML_SINGLE_QUOTED_SCALAR_STYLE; b'|' => YAML_LITERAL_SCALAR_STYLE,
current_block_8 = 17407779659766490442; b'>' => YAML_FOLDED_SCALAR_STYLE,
} else if *start as i32 == '"' as i32 {
*style = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
current_block_8 = 17407779659766490442;
} else if *start as i32 == '|' as i32 {
*style = YAML_LITERAL_SCALAR_STYLE;
current_block_8 = 17407779659766490442;
} else if *start as i32 == '>' as i32 {
*style = YAML_FOLDED_SCALAR_STYLE;
current_block_8 = 17407779659766490442;
} else {
start = ptr::null_mut::<i8>();
current_block_8 = 12675440807659640239;
}
match current_block_8 {
12675440807659640239 => {}
_ => { _ => {
start = start.offset(1); start = ptr::null_mut::<i8>();
break; c = c.offset(1);
continue;
} }
} };
start = start.offset(1);
break;
} }
c = c.offset(1); c = c.offset(1);
} }
if start.is_null() { if start.is_null() {
process::abort(); process::abort();
} }
let mut i = 0;
c = start; c = start;
while c < end { while c < end {
if *c as i32 == '\\' as i32 { *value.offset(i) = if *c as u8 == b'\\' {
c = c.offset(1); c = c.offset(1);
if *c as i32 == '\\' as i32 { match *c as u8 {
let fresh0 = i; b'\\' => b'\\' as i8,
i += 1; b'0' => b'\0' as i8,
*value.offset(fresh0 as isize) = '\\' as i32 as i8; b'b' => b'\x08' as i8,
} else if *c as i32 == '0' as i32 { b'n' => b'\n' as i8,
let fresh1 = i; b'r' => b'\r' as i8,
i += 1; b't' => b'\t' as i8,
*value.offset(fresh1 as isize) = '\0' as i32 as i8; _ => process::abort(),
} else if *c as i32 == 'b' as i32 {
let fresh2 = i;
i += 1;
*value.offset(fresh2 as isize) = '\u{8}' as i32 as i8;
} else if *c as i32 == 'n' as i32 {
let fresh3 = i;
i += 1;
*value.offset(fresh3 as isize) = '\n' as i32 as i8;
} else if *c as i32 == 'r' as i32 {
let fresh4 = i;
i += 1;
*value.offset(fresh4 as isize) = '\r' as i32 as i8;
} else if *c as i32 == 't' as i32 {
let fresh5 = i;
i += 1;
*value.offset(fresh5 as isize) = '\t' as i32 as i8;
} else {
process::abort();
} }
} else { } else {
let fresh6 = i; *c
i += 1; };
*value.offset(fresh6 as isize) = *c; i += 1;
}
c = c.offset(1); c = c.offset(1);
} }
*value.offset(i as isize) = '\0' as i32 as i8; *value.offset(i) = b'\0' as i8;
}
unsafe fn memcpy(dest: *mut c_void, src: *const c_void, count: u64) -> *mut c_void {
ptr::copy_nonoverlapping(
src.cast::<MaybeUninit<u8>>(),
dest.cast::<MaybeUninit<u8>>(),
count as usize,
);
dest
}
unsafe fn strchr(mut str: *const i8, c: i32) -> *mut i8 {
loop {
match *str {
0 => return ptr::null_mut(),
curr if curr == c as i8 => return str as *mut i8,
_ => str = str.offset(1),
}
}
}
unsafe fn strlen(str: *const i8) -> u64 {
let mut end = str;
while *end != 0 {
end = end.add(1);
}
end.offset_from(str) as u64
}
unsafe fn strncmp(lhs: *const i8, rhs: *const i8, mut count: u64) -> i32 {
let mut lhs = lhs.cast::<u8>();
let mut rhs = rhs.cast::<u8>();
while count > 0 && *lhs != 0 && *lhs == *rhs {
lhs = lhs.add(1);
rhs = rhs.add(1);
count -= 1;
}
if count == 0 {
0
} else {
(*lhs).cmp(&*rhs) as i32
}
} }
fn main() -> ExitCode { fn main() -> ExitCode {