mirror of
https://github.com/simonask/libyaml-safer
synced 2024-11-23 03:43:03 +00:00
Clean up run-emitter-test-suite implementation
This commit is contained in:
parent
9d367c1b68
commit
df24355436
1 changed files with 129 additions and 230 deletions
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue