From af1c0d21328979aba04fa7eac877f139efa03c11 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:42:56 +0800 Subject: [PATCH 1/6] add mkseq func for brace file --- bash-5.1/r_braces/src/lib.rs | 76 ++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index 6b13ddb..6e5f59b 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -123,6 +123,18 @@ macro_rules! TYPE_WIDTH { } } +#[macro_export] +macro_rules! TYPE_SIGNED { + ($t:ty) => { + if 0 as $t < (-1) as libc::c_int as $t { + 0 as $t + } + else { + 1 as $t + } + } +} + #[macro_export] macro_rules! ISALPHA{ ($c:expr) => { @@ -471,3 +483,67 @@ unsafe extern "C" fn expand_amble( } return result; } + +unsafe extern "C" fn mkseq( + mut start: intmax_t, + mut end: intmax_t, + mut incr: intmax_t, + mut type_0: libc::c_int, + mut width: libc::c_int, +) -> *mut *mut libc::c_char { + let mut n: intmax_t = 0; + let mut prevn: intmax_t = 0; + let mut i: libc::c_int = 0; + let mut nelem: libc::c_int = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + + if incr == 0 as libc::c_int as libc::c_long { + incr = 1 as libc::c_int as intmax_t; + } + + if start > end && incr > 0 as libc::c_int as libc::c_long { + incr = -incr; + } + else if start < end && incr < 0 as libc::c_int as libc::c_long { + if incr == INTMAX_MIN!(){ + return 0 as *mut *mut libc::c_void as *mut *mut libc::c_char; + } + incr = -incr; + } + if SUBOVERFLOW!(end, start, INTMAX_MIN!() + 3, INTMAX_MAX!()-2) + { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + prevn = sh_imaxabs!(end - start); + + if INT_MAX!() == INTMAX_MAX!() && + ADDOVERFLOW!(prevn, 2, INT_MIN!(), INT_MAX!()) + { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + else if ADDOVERFLOW!((prevn/sh_imaxabs!(incr)), 1, INTMAX_MIN!(), INTMAX_MAX!()) + { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if (prevn / sh_imaxabs!(incr)) > INT_MAX!() - 3 as libc::c_int as libc::c_long { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + nelem = (prevn / sh_imaxabs!(incr)) as libc::c_int + 1 as libc::c_int; + result = strvec_mcreate (nelem + 1); + + if result.is_null() { + internal_error( + b"brace expansion: failed to allocate memory for %u elements\0" + as *const u8 as *const libc::c_char, + nelem as libc::c_uint, + ); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + i = 0 as libc::c_int; + n = start; +} + + + -- Gitee From 6a96e3ff8d790e3ababbb796012c563a06c5598a Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:45:47 +0800 Subject: [PATCH 2/6] judge type_0 for mkseq func --- bash-5.1/r_braces/src/lib.rs | 69 ++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index 6e5f59b..4eb387e 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -543,6 +543,75 @@ unsafe extern "C" fn mkseq( } i = 0 as libc::c_int; n = start; + loop { + if interrupt_state != 0 as libc::c_int { + *result.offset(i as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + strvec_dispose(result); + result = 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + if terminating_signal != 0 { + termsig_handler(terminating_signal); + } + if interrupt_state != 0 { + throw_to_top_level(); + } + if type_0 == ST_INT!() { + t = itos(n); + *result.offset(i as isize) = t; + i += 1; + + }else if type_0 == ST_ZINT!() { + let mut len: libc::c_int = 0; + let mut arg: libc::c_int = 0; + arg = n as libc::c_int; + len = asprintf( + &mut t as *mut *mut libc::c_char, + b"%0*d\0" as *const u8 as *const libc::c_char, + width, + arg, + ); + *result.offset(i as isize) = t; + i += 1; + } else { + t = xmalloc(2 as libc::c_int as usize) as *mut libc::c_char; + if !t.is_null() { + *t.offset(0 as libc::c_int as isize) = n as libc::c_char; + *t.offset(1 as libc::c_int as isize) = '\0' as i32 as libc::c_char; + } + *result.offset(i as isize) = t; + i = i + 1; + } + if t.is_null() { + let mut p: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lbuf: [libc::c_char; INT_STRLEN_BOUND!(intmax_t) + 1 as usize] + = [0;INT_STRLEN_BOUND!(intmax_t) + 1 as usize ]; + p = inttostr( + n, + lbuf.as_mut_ptr(), + std::mem::size_of::< + [libc::c_char;INT_STRLEN_BOUND!(intmax_t) + 1 as usize]>() as usize, + ); + internal_error( + b"brace expansion: failed to allocate memory for '%s'\0" as *const u8 + as *const libc::c_char, + p, + ); + strvec_dispose(result); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if ADDOVERFLOW!(n, incr, INTMAX_MIN!(), INTMAX_MAX!()){ + break; + } + n += incr; + if incr < 0 as libc::c_int as libc::c_long && n < end + || incr > 0 as libc::c_int as libc::c_long && n > end + { + break; + } + } + *result.offset(i as isize) = 0 as *mut libc::c_char; + return (result); } -- Gitee From b34ebdaf382c3deca68e338fb88bdc3c5965fd10 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:48:30 +0800 Subject: [PATCH 3/6] add expand_seqterm func for brace file --- bash-5.1/r_braces/src/lib.rs | 163 +++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index 4eb387e..a4d1beb 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -614,5 +614,168 @@ unsafe extern "C" fn mkseq( return (result); } +unsafe extern "C" fn expand_seqterm( + mut text: *mut libc::c_char, + mut tlen: size_t, +) -> *mut *mut libc::c_char { + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut rhs: *mut libc::c_char = 0 as *mut libc::c_char; + let mut lhs_t: libc::c_int = 0; + let mut rhs_t: libc::c_int = 0; + let mut lhs_l: libc::c_int = 0; + let mut rhs_l: libc::c_int = 0; + let mut width: libc::c_int = 0; + let mut lhs_v: intmax_t = 0; + let mut rhs_v: intmax_t = 0; + let mut incr: intmax_t = 0; + let mut tl: intmax_t = 0; + let mut tr: intmax_t = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + let mut ep: *mut libc::c_char = 0 as *mut libc::c_char; + let mut oep: *mut libc::c_char = 0 as *mut libc::c_char; + + t = libc::strstr(text, b"..\0" as *const u8 as *const libc::c_char); + + if t.is_null() { + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + lhs_l = t.offset_from(text) as libc::c_long as libc::c_int; + + lhs = substring(text, 0 as libc::c_int, lhs_l); + rhs = substring( + text, + (lhs_l + std::mem::size_of::<[libc::c_char; 3]> as libc::c_int - 1 as libc::c_int ), + tlen as libc::c_int, + ); + if *lhs.offset(0 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + || *rhs.offset(0 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + lhs_t = if legal_number(lhs, &mut tl) != 0 { + ST_INT!() + } else if ISALPHA!(*lhs) + && *lhs.offset(1 as libc::c_int as isize) as libc::c_int == 0 as libc::c_int + { + ST_CHAR!() as libc::c_int + } else { + ST_BAD!() as libc::c_int + }; + + ep = 0 as *mut libc::c_char; + + if ISDIGIT!(*rhs) || ((*rhs as libc::c_int == '+' as libc::c_int + || *rhs as libc::c_int == '-' as libc::c_int ) + && ISDIGIT! (*rhs.offset(1 as isize))) + { + rhs_t = ST_INT!() as libc::c_int; + errno = 0 as libc::c_int; + tr = strtoimax(rhs, &mut ep, 10 as libc::c_int); + if errno == ERANGE!() + || !ep.is_null() && *ep as libc::c_int != 0 as libc::c_int + && *ep as libc::c_int != '.' as i32 + { + rhs_t = ST_BAD!() as libc::c_int; + } + + } + else if ISALPHA!(*rhs) && *rhs.offset(1 as isize) == 0 + || *rhs.offset(1 as isize) as libc::c_int == '.' as libc::c_int + { + rhs_t = ST_CHAR!(); + ep = rhs.offset(1 as libc::c_int as isize); + } + else { + rhs_t = ST_BAD!(); + ep = 0 as *mut libc::c_char; + } + incr = 1 as libc::c_int as intmax_t; + if rhs_t != ST_BAD!() { + oep = ep; + errno = 0 as libc::c_int; + + if !ep.is_null() && *ep as libc::c_int == '.' as i32 + && *ep.offset(1 as libc::c_int as isize) as libc::c_int == '.' as i32 + && *ep.offset(2 as libc::c_int as isize) as libc::c_int != 0 + { + incr = strtoimax( + ep.offset(2 as libc::c_int as isize), + &mut ep, + 10 as libc::c_int, + ); + } + if *ep as libc::c_int != 0 as libc::c_int + || errno == ERANGE!() + { + rhs_t = ST_BAD!(); + } + tlen = (tlen as usize) + .wrapping_sub(ep.offset_from(oep) as libc::c_long as usize) as size_t + as size_t; + } + + if lhs_t != rhs_t || lhs_t == ST_BAD!() as libc::c_int || rhs_t == ST_BAD!() as libc::c_int { + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + return 0 as *mut libc::c_void as *mut *mut libc::c_char; + } + + if lhs_t == ST_CHAR!() as libc::c_int { + lhs_v = *lhs.offset(0 as libc::c_int as isize) as libc::c_uchar as intmax_t; + rhs_v = *rhs.offset(0 as libc::c_int as isize) as libc::c_uchar as intmax_t; + width = 1 as libc::c_int; + } + else { + lhs_v = tl; + rhs_v = tr; + rhs_l = tlen as libc::c_int - lhs_l as libc::c_int- + std::mem::size_of::<[libc::c_char; 3]>() as libc::c_int + + 1 as libc::c_int; + + width = 0; + if lhs_l > 1 as libc::c_int + && *lhs.offset(0 as libc::c_int as isize) as libc::c_int == '0' as i32 + { + width = lhs_l; + lhs_t = ST_ZINT!() ; + } + if lhs_l > 2 as libc::c_int + && *lhs.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *lhs.offset(1 as libc::c_int as isize) as libc::c_int == '0' as i32 + { + width = lhs_l; + lhs_t = ST_ZINT!() ; + } + if rhs_l > 1 as libc::c_int + && *rhs.offset(0 as libc::c_int as isize) as libc::c_int == '0' as i32 + && width < rhs_l + { + width = rhs_l; + lhs_t = ST_ZINT!() ; + } + if rhs_l > 2 as libc::c_int + && *rhs.offset(0 as libc::c_int as isize) as libc::c_int == '-' as i32 + && *rhs.offset(1 as libc::c_int as isize) as libc::c_int == '0' as i32 + && width < rhs_l + { + width = rhs_l; + lhs_t = ST_ZINT!() ; + } + if width < lhs_l && lhs_t == ST_ZINT!() { + width = lhs_l; + } + if width < rhs_l && lhs_t == ST_ZINT!() { + width = rhs_l; + } + } + result = mkseq(lhs_v, rhs_v, incr, lhs_t, width); + libc::free(lhs as *mut libc::c_void); + libc::free(rhs as *mut libc::c_void); + return result; +} -- Gitee From 083ef515292715e84da802c1ca11f3075d7e6fa2 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:50:47 +0800 Subject: [PATCH 4/6] add brace_gobbler func for brace file --- bash-5.1/r_braces/src/lib.rs | 61 ++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index a4d1beb..7ef2da6 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -135,6 +135,23 @@ macro_rules! TYPE_SIGNED { } } +#[macro_export] +macro_rules! ADVANCE_CHAR { + ($str:expr, $strsize:expr, $i:expr) => { + $i += 1; + } +} + +#[macro_export] +macro_rules! brace_whitespace{ + ($c:expr) => { + $c == 0 + || $c as libc::c_int == ' ' as i32 + || $c as libc::c_int == '\t' as i32 + || $c as libc::c_int == '\n' as i32 + } +} + #[macro_export] macro_rules! ISALPHA{ ($c:expr) => { @@ -779,3 +796,47 @@ unsafe extern "C" fn expand_seqterm( return result; } +unsafe extern "C" fn brace_gobbler( + mut text: *mut libc::c_char, + mut tlen: size_t, + mut indx: *mut libc::c_int, + mut satisfy: libc::c_int, +) -> libc::c_int { + let mut i: libc::c_int = 0; + let mut c: libc::c_int = 0; + let mut quoted: libc::c_int = 0; + let mut level: libc::c_int = 0; + let mut commas: libc::c_int = 0; + let mut pass_next: libc::c_int = 0; + let mut si: libc::c_int = 0; + let mut t: *mut libc::c_char = 0 as *mut libc::c_char; + let mut Flag = false; + + let mut state: mbstate_t = mbstate_t { + __count: 0, + __value: __mbstate_t__bindgen_ty_1 { __wch: 0 }, + }; + libc::memset( + &mut state as *mut mbstate_t as *mut libc::c_void, + '\0' as i32, + std::mem::size_of::() as usize, + ); + + pass_next = 0 as libc::c_int; + quoted = pass_next; + level = quoted; + commas = if satisfy == '}' as i32 + { + 0 as libc::c_int + } + else + { + 1 as libc::c_int + }; + i = *indx; + libc::free(arr1 as *mut libc::c_void); + *result.offset(len as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + return result; +} + + -- Gitee From 3f68d259eb1a2892c5b7fd38b3d213f5bace7aa3 Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:54:28 +0800 Subject: [PATCH 5/6] add goto logic for brace_gobbler func --- bash-5.1/r_braces/src/lib.rs | 126 +++++++++++++++++++++++++++++++++-- 1 file changed, 122 insertions(+), 4 deletions(-) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index 7ef2da6..57c14ab 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -834,9 +834,127 @@ unsafe extern "C" fn brace_gobbler( 1 as libc::c_int }; i = *indx; - libc::free(arr1 as *mut libc::c_void); - *result.offset(len as isize) = 0 as *mut libc::c_void as *mut libc::c_char; - return result; -} + 'outer: loop { + Flag = false; + c = *text.offset(i as isize) as libc::c_int; + if (c == 0) { + + break 'outer; + } + if pass_next != 0 { + pass_next = 0 as libc::c_int; + ADVANCE_CHAR!(text, tlen, i); + continue 'outer; + } + if c == '\\' as i32 + && (quoted == 0 || quoted == '"' as i32 + || quoted == '`' as i32 + ){ + + pass_next = 1; + i += 1; + continue 'outer; + } + if c == '$' as i32 + && *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int == '{' as i32 + && quoted != '\'' as i32 + { + pass_next = 1 as libc::c_int; + i += 1; + if quoted == 0 as libc::c_int { + level += 1; + } + continue 'outer; + } + 'inner: loop { + if quoted != 0 { + if c == quoted { + quoted = 0 as libc::c_int; + } + if quoted == '"' as i32 && c == '$' as i32 + && *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '(' as i32 + { + Flag = true; + break 'inner; + } + ADVANCE_CHAR!(text, tlen, i); + continue 'outer; + } + if c == '"' as libc::c_int + || c == '\'' as libc::c_int + || c == '`' as libc::c_int + { + quoted = c; + i+= 1; + continue 'outer; + } + else if (c == '$' as libc::c_int + || c == '<' as libc::c_int + || c == '>' as libc::c_int ) && + *text.offset((i + 1 as libc::c_int) as isize) as libc::c_int + == '(' as libc::c_int /* ) */ + { + si = i + 2 as libc::c_int; + t = extract_command_subst(text, &mut si, 0 as libc::c_int); + i = si; + libc::free(t as *mut libc::c_void); + i += 1; + continue 'outer; + } + break 'inner; + } + + if Flag { + si = i + 2 as libc::c_int; + t = extract_command_subst(text, &mut si, 0 as libc::c_int); + i = si; + libc::free(t as *mut libc::c_void); + i += 1; + continue 'outer; + } + + if (c == satisfy + && level == 0 as libc::c_int + && quoted == 0 as libc::c_int + && commas > 0 as libc::c_int) + { + /* We ignore an open brace surrounded by whitespace, and also + an open brace followed immediately by a close brace preceded + by whitespace. */ + if c == '{' as libc::c_int && + ((i == 0 + || brace_whitespace!(*text.offset((i - 1 as libc::c_int) as isize))) + && + (brace_whitespace!(*text.offset((i + 1 as libc::c_int) as isize)) + || *text.offset((i + 1 as libc::c_int) as isize) + as libc::c_int == '}' as i32 )) + { + i += 1; + continue 'outer; + } + break 'outer; + } + + if c == '{' as i32 { + level += 1; + } else if c == '}' as i32 && level != 0 { + level -= 1; + } else if satisfy == '}' as i32 && c == brace_arg_separator + && level == 0 as libc::c_int + { + commas += 1; + } else if satisfy == '}' as i32 + && STREQN(text.offset(i as libc::c_int as isize) , BRACE_SEQ_SPECIFIER!(), 2) + && *text.offset((i + 2 as libc::c_int) as isize) as libc::c_int != satisfy + && level == 0 as libc::c_int { + commas += 1; + } + ADVANCE_CHAR!(text, tlen, i); + } + + *indx = i; + return c; +} -- Gitee From a9b9a516b9f8d64ba36deb8f8578759ac00bbeab Mon Sep 17 00:00:00 2001 From: zhanghuanhuan Date: Thu, 2 Nov 2023 13:55:58 +0800 Subject: [PATCH 6/6] add array_concat func for brace file --- bash-5.1/r_braces/src/lib.rs | 99 ++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/bash-5.1/r_braces/src/lib.rs b/bash-5.1/r_braces/src/lib.rs index 57c14ab..2a84456 100644 --- a/bash-5.1/r_braces/src/lib.rs +++ b/bash-5.1/r_braces/src/lib.rs @@ -135,6 +135,31 @@ macro_rules! TYPE_SIGNED { } } +#[macro_export] +macro_rules! INT_STRLEN_BOUND { + ($t:ty) => { + (std::mem::size_of::<$t>() * CHAR_BIT as usize) + - TYPE_SIGNED!($t) as usize * 302 as usize / 1000 as usize + + 1 as usize + TYPE_SIGNED!($t) as usize + } +} + +#[macro_export] +macro_rules! SUBOVERFLOW { + ($a:expr,$b:expr,$minv:expr,$maxv:expr) => { + ($b > 0 as libc::c_long && $a < ($minv + $b)) || + ($b < 0 as libc::c_long && $a < ($maxv + $b)) + } +} + +#[macro_export] +macro_rules! ADDOVERFLOW { + ($a:expr,$b:expr,$minv:expr,$maxv:expr) => { + ($a > 0 as libc::c_long && $b > ($maxv - $a)) || + ($a < 0 as libc::c_long && $b < ($minv + $a)) + } +} + #[macro_export] macro_rules! ADVANCE_CHAR { ($str:expr, $strsize:expr, $i:expr) => { @@ -958,3 +983,77 @@ unsafe extern "C" fn brace_gobbler( return c; } +unsafe extern "C" fn array_concat( + mut arr1: *mut *mut libc::c_char, + mut arr2: *mut *mut libc::c_char, +) -> *mut *mut libc::c_char { + let mut i: libc::c_int = 0; + let mut j: libc::c_int = 0; + let mut len: libc::c_int = 0; + let mut len1: libc::c_int = 0; + let mut len2: libc::c_int = 0; + let mut result: *mut *mut libc::c_char = 0 as *mut *mut libc::c_char; + + if arr1.is_null() { + return arr2; + } + + if arr2.is_null() { + return arr1; + } + + if !(*arr1.offset(0 as libc::c_int as isize)).is_null() + && *(*arr1.offset(0 as libc::c_int as isize)).offset(0 as libc::c_int as isize) + as libc::c_int == 0 as libc::c_int + && (*arr1.offset(1 as libc::c_int as isize)).is_null() + { + strvec_dispose(arr1); + return arr2; + } + if !(*arr2.offset(0 as libc::c_int as isize)).is_null() + && *(*arr2.offset(0 as libc::c_int as isize)).offset(0 as libc::c_int as isize) + as libc::c_int == 0 as libc::c_int + && (*arr2.offset(1 as libc::c_int as isize)).is_null() + { + return arr1; + } + + len1 = strvec_len(arr1); + len2 = strvec_len(arr2); + result = xmalloc( + ((1 as libc::c_int + len1 * len2) as usize) + .wrapping_mul(std::mem::size_of::<*mut libc::c_char>() as usize), + ) as *mut *mut libc::c_char; + if result.is_null() { + return result; + } + + len = 0 as libc::c_int; + i = 0 as libc::c_int; + + while i < len1 { + let mut strlen_1: libc::c_int = libc::strlen(*arr1.offset(i as isize)) as libc::c_int; + j = 0 as libc::c_int; + while j < len2 + { + *result.offset(len as isize)= + xmalloc((1 as libc::c_int + strlen_1 + + libc::strlen(*arr2.offset(j as isize)) as libc::c_int) + as size_t) as *mut libc::c_char; + + libc::strcpy(*result.offset(len as isize), *arr1.offset(i as isize)); + libc::strcpy( + (*result.offset(len as isize)).offset(strlen_1 as isize), + *arr2.offset(j as isize), + ); + len += 1; + j += 1; + } + libc::free(*arr1.offset(i as isize) as *mut libc::c_void); + i += 1 + } + libc::free(arr1 as *mut libc::c_void); + *result.offset(len as isize) = 0 as *mut libc::c_void as *mut libc::c_char; + return result; +} + -- Gitee