#[expect(
clippy::char_lit_as_u8,
reason = "TODO investigate, originally generated by c2rust"
)]
pub unsafe fn unvis(cp: *mut u8, c: u8, astate: *mut i32, flag: i32) -> i32 {
unsafe {
if flag & 1 != 0 {
if *astate == 5 || *astate == 6 {
*astate = 0;
return 1;
}
return if *astate == 0 { 3 } else { -1 };
}
match *astate {
0 => {
*cp = 0;
if c == b'\\' {
*astate = 1;
return 0;
}
*cp = c;
1
}
1 => {
match c as libc::c_int {
92 => {
*cp = c;
*astate = 0;
return 1;
}
48..=55 => {
*cp = c - b'0';
*astate = 5;
return 0;
}
77 => {
*cp = 0o200i32 as u8;
*astate = 2;
return 0;
}
94 => {
*astate = 4;
return 0;
}
110 => {
*cp = b'\n';
*astate = 0;
return 1;
}
114 => {
*cp = b'\r';
*astate = 0;
return 1;
}
98 => {
*cp = '\u{8}' as u8;
*astate = 0;
return 1;
}
97 => {
*cp = '\u{7}' as u8;
*astate = 0;
return 1;
}
118 => {
*cp = '\u{b}' as u8;
*astate = 0;
return 1;
}
116 => {
*cp = b'\t';
*astate = 0;
return 1;
}
102 => {
*cp = '\u{c}' as u8;
*astate = 0;
return 1;
}
115 => {
*cp = b' ';
*astate = 0;
return 1;
}
69 => {
*cp = '\u{1b}' as u8;
*astate = 0;
return 1;
}
10 | 36 => {
*astate = 0;
return 3;
}
_ => {}
}
*astate = 0;
-1
}
2 => {
if c == b'-' {
*astate = 3;
} else if c == b'^' {
*astate = 4;
} else {
*astate = 0;
return -1;
}
0
}
3 => {
*astate = 0;
*cp |= c;
1
}
4 => {
if c == b'?' {
*cp = (*cp as libc::c_int | 0o177 as libc::c_int) as u8;
} else {
*cp = (*cp as libc::c_int | c as libc::c_int & 0o37 as libc::c_int) as u8;
}
*astate = 0;
1
}
5 => {
if (b'0'..=b'7').contains(&c) {
*cp = (((*cp as libc::c_int) << 3 as libc::c_int) + (c - b'0') as i32) as u8;
*astate = 6;
return 0;
}
*astate = 0;
2
}
6 => {
*astate = 0 as libc::c_int;
if (b'0'..=b'7').contains(&c) {
*cp = (((*cp as libc::c_int) << 3 as libc::c_int) + (c - b'0') as i32) as u8;
return 1;
}
2
}
_ => {
*astate = 0;
-1
}
}
}
}
pub unsafe fn strunvis(mut dst: *mut u8, mut src: *const u8) -> i32 {
unsafe {
let mut c: u8;
let start: *mut u8 = dst;
let mut state: i32 = 0;
loop {
let fresh0 = src;
src = src.add(1);
c = *fresh0;
if c == 0 {
break;
}
loop {
match unvis(dst, c, &mut state, 0 as libc::c_int) {
1 => {
dst = dst.add(1);
break;
}
2 => {
dst = dst.add(1);
}
0 | 3 => {
break;
}
_ => {
*dst = b'\0';
return -1;
}
}
}
}
if unvis(dst, c, &mut state, 1 as libc::c_int) == 1 as libc::c_int {
dst = dst.add(1);
}
*dst = b'\0';
dst.offset_from(start) as i32
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_strunvis_literals() {
let src = crate::c!("abc");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 3);
assert_eq!(&dst[..4], b"abc\0");
}
#[test]
fn test_strunvis_escaped_tab() {
let src = crate::c!("\\t");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(dst[0], b'\t');
assert_eq!(dst[1], b'\0');
}
#[test]
fn test_strunvis_escaped_newline() {
let src = crate::c!("a\\nb");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 3);
assert_eq!(&dst[..4], b"a\nb\0");
}
#[test]
fn test_strunvis_octal() {
let src = crate::c!("\\101");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(dst[0], b'A');
assert_eq!(dst[1], b'\0');
}
#[test]
fn test_strunvis_escaped_backslash() {
let src = crate::c!("\\\\");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(dst[0], b'\\');
assert_eq!(dst[1], b'\0');
}
#[test]
fn test_strunvis_mixed() {
let src = crate::c!("a\\tb\\101c");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 5);
assert_eq!(&dst[..6], b"a\tbAc\0");
}
#[test]
fn test_strunvis_named_escapes() {
let src = crate::c!("\\r\\b\\a\\v\\f\\s\\E");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 7);
assert_eq!(&dst[..8], &[0x0d, 0x08, 0x07, 0x0b, 0x0c, 0x20, 0x1b, 0x00]);
}
#[test]
fn test_strunvis_octal_three_digit() {
let src = crate::c!("\\377");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0xFF);
assert_eq!(dst[1], b'\0');
}
#[test]
fn test_strunvis_octal_flushed_at_end() {
let src = crate::c!("\\7");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0x07);
}
#[test]
fn test_strunvis_octal_pushback() {
let src = crate::c!("\\77x");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 2);
assert_eq!(&dst[..3], &[0x3F, b'x', 0x00]);
}
#[test]
fn test_strunvis_meta() {
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), crate::c!("\\M-A")) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0xC1);
let mut dst2 = [0u8; 16];
let ret2 = unsafe { strunvis(dst2.as_mut_ptr(), crate::c!("\\M^A")) };
assert_eq!(ret2, 1);
assert_eq!(dst2[0], 0x81);
}
#[test]
fn test_strunvis_control() {
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), crate::c!("\\^A")) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0x01);
let mut dst2 = [0u8; 16];
let ret2 = unsafe { strunvis(dst2.as_mut_ptr(), crate::c!("\\^?")) };
assert_eq!(ret2, 1);
assert_eq!(dst2[0], 0x7F);
}
#[test]
fn test_strunvis_hidden_markers() {
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), crate::c!("a\\\nb")) };
assert_eq!(ret, 2);
assert_eq!(&dst[..3], b"ab\0");
let mut dst2 = [0u8; 16];
let ret2 = unsafe { strunvis(dst2.as_mut_ptr(), crate::c!("a\\$b")) };
assert_eq!(ret2, 2);
assert_eq!(&dst2[..3], b"ab\0");
}
#[test]
fn test_strunvis_invalid_escape() {
let src = crate::c!("\\z");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, -1);
}
#[test]
fn test_strunvis_trailing_backslash() {
let src = crate::c!("a\\");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 1);
assert_eq!(&dst[..2], b"a\0");
}
#[test]
fn test_strunvis_multiple_octal() {
let src = crate::c!("\\101\\102\\103");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 3);
assert_eq!(&dst[..4], b"ABC\0");
}
#[test]
fn test_strunvis_octal_stops_at_three_digits() {
let src = crate::c!("\\1011");
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), src) };
assert_eq!(ret, 2);
assert_eq!(&dst[..3], b"A1\0");
}
#[test]
fn test_strunvis_control_at_and_esc() {
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), crate::c!("\\^@")) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0x00);
let mut dst2 = [0u8; 16];
let ret2 = unsafe { strunvis(dst2.as_mut_ptr(), crate::c!("\\^[")) };
assert_eq!(ret2, 1);
assert_eq!(dst2[0], 0x1B);
}
#[test]
fn test_strunvis_meta_control_del() {
let mut dst = [0u8; 16];
let ret = unsafe { strunvis(dst.as_mut_ptr(), crate::c!("\\M^?")) };
assert_eq!(ret, 1);
assert_eq!(dst[0], 0xFF);
}
}