checker: check `unsafe` V function calls (#8752)

pull/8757/head
Nick Treleaven 2021-02-14 18:31:42 +00:00 committed by GitHub
parent d3bcd5d305
commit ea803113c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 200 additions and 161 deletions

View File

@ -341,7 +341,7 @@ fn my_init(mut app App) {
w := 256 w := 256
h := 256 h := 256
sz := w * h * 4 sz := w * h * 4
tmp_txt := malloc(sz) tmp_txt := unsafe {malloc(sz)}
mut i := 0 mut i := 0
for i < sz { for i < sz {
unsafe { unsafe {
@ -370,8 +370,10 @@ fn my_init(mut app App) {
i += 4 i += 4
} }
} }
unsafe {
app.texture = create_texture(w, h, tmp_txt) app.texture = create_texture(w, h, tmp_txt)
free(tmp_txt) free(tmp_txt)
}
} }
fn cleanup(mut app App) { fn cleanup(mut app App) {

View File

@ -331,7 +331,7 @@ fn my_init(mut app App) {
w := 256 w := 256
h := 256 h := 256
sz := w * h * 4 sz := w * h * 4
tmp_txt := malloc(sz) tmp_txt := unsafe {malloc(sz)}
mut i := 0 mut i := 0
for i < sz { for i < sz {
unsafe { unsafe {
@ -360,9 +360,10 @@ fn my_init(mut app App) {
i += 4 i += 4
} }
} }
unsafe {
app.texture = create_texture(w, h, tmp_txt) app.texture = create_texture(w, h, tmp_txt)
free(tmp_txt) free(tmp_txt)
}
// glsl // glsl
init_cube_glsl(mut app) init_cube_glsl(mut app)
app.init_flag = true app.init_flag = true

View File

@ -300,7 +300,7 @@ fn (mut b Buffer) free() {
eprintln(@MOD + '.' + @STRUCT + '::' + @FN) eprintln(@MOD + '.' + @STRUCT + '::' + @FN)
} }
for line in b.lines { for line in b.lines {
line.free() unsafe {line.free()}
} }
unsafe { b.lines.free() } unsafe { b.lines.free() }
} }

View File

@ -145,7 +145,7 @@ fn main() {
app.ttf_render << &ttf.TTF_render_Sokol{ app.ttf_render << &ttf.TTF_render_Sokol{
bmp: &ttf.BitMap{ bmp: &ttf.BitMap{
tf: &(app.tf[0]) tf: &(app.tf[0])
buf: malloc(32000000) buf: unsafe {malloc(32000000)}
buf_size: (32000000) buf_size: (32000000)
color: 0xFF0000FF color: 0xFF0000FF
// style: .raw // style: .raw

View File

@ -98,7 +98,7 @@ fn (mut a array) ensure_cap(required int) {
new_size := cap * a.element_size new_size := cap * a.element_size
mut new_data := byteptr(0) mut new_data := byteptr(0)
if a.cap > 0 { if a.cap > 0 {
new_data = v_realloc(a.data, new_size) new_data = unsafe { v_realloc(a.data, new_size) }
} else { } else {
new_data = vcalloc(new_size) new_data = vcalloc(new_size)
} }
@ -274,7 +274,7 @@ pub fn (mut a array) pop() voidptr {
a.len = new_len a.len = new_len
// NB: a.cap is not changed here *on purpose*, so that // NB: a.cap is not changed here *on purpose*, so that
// further << ops on that array will be more efficient. // further << ops on that array will be more efficient.
return memdup(last_elem, a.element_size) return unsafe { memdup(last_elem, a.element_size) }
} }
// delete_last efficiently deletes the last element of the array. // delete_last efficiently deletes the last element of the array.
@ -507,7 +507,7 @@ pub fn (a []string) str() string {
// hex returns a string with the hexadecimal representation // hex returns a string with the hexadecimal representation
// of the byte elements of the array. // of the byte elements of the array.
pub fn (b []byte) hex() string { pub fn (b []byte) hex() string {
mut hex := malloc(b.len * 2 + 1) mut hex := unsafe { malloc(b.len * 2 + 1) }
mut dst_i := 0 mut dst_i := 0
for i in b { for i in b {
n0 := i >> 4 n0 := i >> 4

View File

@ -216,7 +216,6 @@ pub fn v_realloc(b byteptr, n int) byteptr {
// v_calloc dynamically allocates a zeroed `n` bytes block of memory on the heap. // v_calloc dynamically allocates a zeroed `n` bytes block of memory on the heap.
// v_calloc returns a `byteptr` pointing to the memory address of the allocated space. // v_calloc returns a `byteptr` pointing to the memory address of the allocated space.
[unsafe]
pub fn v_calloc(n int) byteptr { pub fn v_calloc(n int) byteptr {
return C.calloc(1, n) return C.calloc(1, n)
} }
@ -224,7 +223,6 @@ pub fn v_calloc(n int) byteptr {
// vcalloc dynamically allocates a zeroed `n` bytes block of memory on the heap. // vcalloc dynamically allocates a zeroed `n` bytes block of memory on the heap.
// vcalloc returns a `byteptr` pointing to the memory address of the allocated space. // vcalloc returns a `byteptr` pointing to the memory address of the allocated space.
// Unlike `v_calloc` vcalloc checks for negative values given in `n`. // Unlike `v_calloc` vcalloc checks for negative values given in `n`.
[unsafe]
pub fn vcalloc(n int) byteptr { pub fn vcalloc(n int) byteptr {
if n < 0 { if n < 0 {
panic('calloc(<=0)') panic('calloc(<=0)')
@ -246,6 +244,7 @@ pub fn free(ptr voidptr) {
// memdup dynamically allocates a `sz` bytes block of memory on the heap // memdup dynamically allocates a `sz` bytes block of memory on the heap
// memdup then copies the contents of `src` into the allocated space and // memdup then copies the contents of `src` into the allocated space and
// returns a pointer to the newly allocated space. // returns a pointer to the newly allocated space.
[unsafe]
pub fn memdup(src voidptr, sz int) voidptr { pub fn memdup(src voidptr, sz int) voidptr {
if sz == 0 { if sz == 0 {
return vcalloc(1) return vcalloc(1)

View File

@ -116,9 +116,11 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
} }
buf := [1000]byte{} buf := [1000]byte{}
mut output := '' mut output := ''
unsafe {
for C.fgets(charptr(buf), 1000, f) != 0 { for C.fgets(charptr(buf), 1000, f) != 0 {
output += tos(byteptr(buf), vstrlen(byteptr(buf))) output += tos(byteptr(buf), vstrlen(byteptr(buf)))
} }
}
output = output.trim_space() + ':' output = output.trim_space() + ':'
if C.pclose(f) != 0 { if C.pclose(f) != 0 {
eprintln(sframe) eprintln(sframe)

View File

@ -65,7 +65,7 @@ fn (nn int) str_l(max int) string {
if n == 0 { if n == 0 {
return '0' return '0'
} }
mut buf := malloc(max + 1) mut buf := unsafe {malloc(max + 1)}
mut is_neg := false mut is_neg := false
if n < 0 { if n < 0 {
n = -n n = -n
@ -136,7 +136,7 @@ pub fn (nn u32) str() string {
return '0' return '0'
} }
max := 12 max := 12
mut buf := malloc(max + 1) mut buf := unsafe {malloc(max + 1)}
mut index := max mut index := max
unsafe { unsafe {
buf[index--] = `\0` buf[index--] = `\0`
@ -283,7 +283,7 @@ fn u64_to_hex(nn u64, len byte) string {
n = n >> 4 n = n >> 4
} }
return string{ return string{
str: memdup(buf, len + 1) str: unsafe {memdup(buf, len + 1)}
len: len len: len
} }
} }
@ -306,7 +306,7 @@ fn u64_to_hex_no_leading_zeros(nn u64, len byte) string {
} }
res_len := len - i res_len := len - i
return string{ return string{
str: memdup(&buf[i], res_len + 1) str: unsafe {memdup(&buf[i], res_len + 1)}
len: res_len len: res_len
} }
} }
@ -448,7 +448,7 @@ pub fn (b byte) str() string {
// Example: assert byte(97).ascii_str() == 'a' // Example: assert byte(97).ascii_str() == 'a'
pub fn (b byte) ascii_str() string { pub fn (b byte) ascii_str() string {
mut str := string{ mut str := string{
str: malloc(2) str: unsafe {malloc(2)}
len: 1 len: 1
} }
unsafe { unsafe {

View File

@ -107,7 +107,6 @@ mut:
} }
[inline] [inline]
[unsafe]
fn new_dense_array(key_bytes int, value_bytes int) DenseArray { fn new_dense_array(key_bytes int, value_bytes int) DenseArray {
slot_bytes := key_bytes + value_bytes slot_bytes := key_bytes + value_bytes
cap := 8 cap := 8
@ -119,7 +118,7 @@ fn new_dense_array(key_bytes int, value_bytes int) DenseArray {
len: 0 len: 0
deletes: 0 deletes: 0
all_deleted: 0 all_deleted: 0
data: malloc(cap * slot_bytes) data: unsafe { malloc(cap * slot_bytes) }
} }
} }
@ -166,7 +165,7 @@ fn (mut d DenseArray) expand() int {
// Move all zeros to the end of the array and resize array // Move all zeros to the end of the array and resize array
fn (mut d DenseArray) zeros_to_end() { fn (mut d DenseArray) zeros_to_end() {
// TODO alloca? // TODO alloca?
mut tmp_buf := malloc(d.slot_bytes) mut tmp_buf := unsafe { malloc(d.slot_bytes) }
mut count := 0 mut count := 0
for i in 0 .. d.len { for i in 0 .. d.len {
if d.has_index(i) { if d.has_index(i) {
@ -179,10 +178,12 @@ fn (mut d DenseArray) zeros_to_end() {
count++ count++
} }
} }
unsafe {
free(tmp_buf) free(tmp_buf)
d.deletes = 0 d.deletes = 0
// TODO: reallocate instead as more deletes are likely // TODO: reallocate instead as more deletes are likely
free(d.all_deleted) free(d.all_deleted)
}
d.len = count d.len = count
d.cap = if count < 8 { 8 } else { count } d.cap = if count < 8 { 8 } else { count }
unsafe { unsafe {
@ -303,7 +304,9 @@ fn map_clone_int_8(dest voidptr, pkey voidptr) {
} }
fn map_free_string(pkey voidptr) { fn map_free_string(pkey voidptr) {
(*unsafe { &string(pkey) }).free() unsafe {
(*&string(pkey)).free()
}
} }
fn map_free_nop(_ voidptr) { fn map_free_nop(_ voidptr) {
@ -617,10 +620,13 @@ fn (mut d DenseArray) delete(i int) {
// delete this // delete this
pub fn (mut m map) delete(key string) { pub fn (mut m map) delete(key string) {
unsafe {
m.delete_1(&key) m.delete_1(&key)
}
} }
// Removes the mapping of a particular key from the map. // Removes the mapping of a particular key from the map.
[unsafe]
pub fn (mut m map) delete_1(key voidptr) { pub fn (mut m map) delete_1(key voidptr) {
mut index, mut meta := m.key_to_index(key) mut index, mut meta := m.key_to_index(key)
index, meta = m.meta_less(index, meta) index, meta = m.meta_less(index, meta)
@ -737,7 +743,7 @@ pub fn (m &map) clone() map {
cached_hashbits: m.cached_hashbits cached_hashbits: m.cached_hashbits
shift: m.shift shift: m.shift
key_values: unsafe { m.key_values.clone() } key_values: unsafe { m.key_values.clone() }
metas: &u32(malloc(metasize)) metas: unsafe { &u32(malloc(metasize)) }
extra_metas: m.extra_metas extra_metas: m.extra_metas
len: m.len len: m.len
has_string_keys: m.has_string_keys has_string_keys: m.has_string_keys

View File

@ -106,8 +106,8 @@ fn (mut m SortedMap) set(key string, value voidptr) {
j-- j--
} }
node.keys[j + 1] = key node.keys[j + 1] = key
node.values[j + 1] = malloc(m.value_bytes)
unsafe { unsafe {
node.values[j + 1] = malloc(m.value_bytes)
C.memcpy(node.values[j + 1], value, m.value_bytes) C.memcpy(node.values[j + 1], value, m.value_bytes)
} }
node.len++ node.len++
@ -129,17 +129,17 @@ fn (mut n mapnode) split_child(child_index int, mut y mapnode) {
z.values[j] = y.values[j + degree] z.values[j] = y.values[j + degree]
} }
if !isnil(y.children) { if !isnil(y.children) {
z.children = &voidptr(malloc(int(children_bytes))) z.children = unsafe {&voidptr(malloc(int(children_bytes)))}
for jj := degree - 1; jj >= 0; jj-- { for jj := degree - 1; jj >= 0; jj-- {
unsafe { unsafe {
z.children[jj] = y.children[jj + degree] z.children[jj] = y.children[jj + degree]
} }
} }
} }
unsafe {
if isnil(n.children) { if isnil(n.children) {
n.children = &voidptr(malloc(int(children_bytes))) n.children = &voidptr(malloc(int(children_bytes)))
} }
unsafe {
n.children[n.len + 1] = n.children[n.len] n.children[n.len + 1] = n.children[n.len]
} }
for j := n.len; j > child_index; j-- { for j := n.len; j > child_index; j-- {

View File

@ -73,7 +73,7 @@ pub fn vstrlen(s byteptr) int {
// tos converts a C string to a V string. // tos converts a C string to a V string.
// String data is reused, not copied. // String data is reused, not copied.
[unsafe] //[unsafe]
pub fn tos(s byteptr, len int) string { pub fn tos(s byteptr, len int) string {
// This should never happen. // This should never happen.
if s == 0 { if s == 0 {
@ -98,7 +98,7 @@ pub fn tos2(s byteptr) string {
} }
return string{ return string{
str: s str: s
len: vstrlen(s) len: unsafe { vstrlen(s) }
} }
} }
@ -245,7 +245,7 @@ pub fn (s string) replace(rep string, with string) string {
} }
// Now we know the number of replacements we need to do and we can calc the len of the new string // Now we know the number of replacements we need to do and we can calc the len of the new string
new_len := s.len + idxs.len * (with.len - rep.len) new_len := s.len + idxs.len * (with.len - rep.len)
mut b := malloc(new_len + 1) // add a newline just in case mut b := unsafe { malloc(new_len + 1) } // add a newline just in case
// Fill the new string // Fill the new string
mut idx_pos := 0 mut idx_pos := 0
mut cur_idx := idxs[idx_pos] mut cur_idx := idxs[idx_pos]
@ -348,7 +348,7 @@ pub fn (s string) replace_each(vals []string) string {
return s return s
} }
idxs.sort2() idxs.sort2()
mut b := malloc(new_len + 1) // add a \0 just in case mut b := unsafe { malloc(new_len + 1) } // add a \0 just in case
// Fill the new string // Fill the new string
mut idx_pos := 0 mut idx_pos := 0
mut cur_idx := idxs[idx_pos] mut cur_idx := idxs[idx_pos]
@ -491,7 +491,7 @@ fn (s string) ge(a string) bool {
fn (s string) add(a string) string { fn (s string) add(a string) string {
new_len := a.len + s.len new_len := a.len + s.len
mut res := string{ mut res := string{
str: malloc(new_len + 1) str: unsafe { malloc(new_len + 1) }
len: new_len len: new_len
} }
for j in 0 .. s.len { for j in 0 .. s.len {
@ -608,7 +608,7 @@ pub fn (s string) substr(start int, end int) string {
return s.clone() return s.clone()
} }
mut res := string{ mut res := string{
str: malloc(len + 1) str: unsafe { malloc(len + 1) }
len: len len: len
} }
for i in 0 .. len { for i in 0 .. len {
@ -1384,6 +1384,7 @@ pub fn (c byte) is_letter() bool {
} }
// free allows for manually freeing the memory occupied by the string // free allows for manually freeing the memory occupied by the string
[unsafe]
pub fn (s &string) free() { pub fn (s &string) free() {
$if prealloc { $if prealloc {
return return
@ -1395,7 +1396,9 @@ pub fn (s &string) free() {
if s.is_lit == 1 || s.len == 0 { if s.is_lit == 1 || s.len == 0 {
return return
} }
unsafe {
free(s.str) free(s.str)
}
s.is_lit = -98761234 s.is_lit = -98761234
} }
@ -1489,7 +1492,7 @@ pub fn (a []string) join(del string) string {
// Allocate enough memory // Allocate enough memory
mut res := '' mut res := ''
res.len = len res.len = len
res.str = malloc(res.len + 1) res.str = unsafe { malloc(res.len + 1) }
mut idx := 0 mut idx := 0
// Go thru every string and copy its every char one by one // Go thru every string and copy its every char one by one
for i, val in a { for i, val in a {
@ -1527,7 +1530,7 @@ pub fn (s string) reverse() string {
return s return s
} }
mut res := string{ mut res := string{
str: malloc(s.len) str: unsafe { malloc(s.len) }
len: s.len len: s.len
} }
for i := s.len - 1; i >= 0; i-- { for i := s.len - 1; i >= 0; i-- {
@ -1586,7 +1589,7 @@ pub fn (s string) repeat(count int) string {
} else if count == 1 { } else if count == 1 {
return s return s
} }
mut ret := malloc(s.len * count + 1) mut ret := unsafe { malloc(s.len * count + 1) }
for i in 0 .. count { for i in 0 .. count {
for j in 0 .. s.len { for j in 0 .. s.len {
unsafe { unsafe {
@ -1635,7 +1638,7 @@ pub fn (s string) strip_margin_custom(del byte) string {
} }
// don't know how much space the resulting string will be, but the max it // don't know how much space the resulting string will be, but the max it
// can be is this big // can be is this big
mut ret := malloc(s.len + 1) mut ret := unsafe { malloc(s.len + 1) }
mut count := 0 mut count := 0
for i := 0; i < s.len; i++ { for i := 0; i < s.len; i++ {
if s[i] in [`\n`, `\r`] { if s[i] in [`\n`, `\r`] {

View File

@ -6,14 +6,16 @@ const (
pub fn (_str string) to_wide() &u16 { pub fn (_str string) to_wide() &u16 {
$if windows { $if windows {
unsafe {
num_chars := (C.MultiByteToWideChar(cp_utf8, 0, charptr(_str.str), _str.len, 0, num_chars := (C.MultiByteToWideChar(cp_utf8, 0, charptr(_str.str), _str.len, 0,
0)) 0))
mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t) mut wstr := &u16(malloc((num_chars + 1) * 2)) // sizeof(wchar_t)
if wstr != 0 { if wstr != 0 {
C.MultiByteToWideChar(cp_utf8, 0, charptr(_str.str), _str.len, wstr, num_chars) C.MultiByteToWideChar(cp_utf8, 0, charptr(_str.str), _str.len, wstr, num_chars)
unsafe {C.memset(&byte(wstr) + num_chars * 2, 0, 2)} C.memset(&byte(wstr) + num_chars * 2, 0, 2)
} }
return wstr return wstr
}
} $else { } $else {
return 0 return 0
} }
@ -21,8 +23,10 @@ pub fn (_str string) to_wide() &u16 {
pub fn string_from_wide(_wstr &u16) string { pub fn string_from_wide(_wstr &u16) string {
$if windows { $if windows {
unsafe {
wstr_len := C.wcslen(_wstr) wstr_len := C.wcslen(_wstr)
return string_from_wide2(_wstr, wstr_len) return string_from_wide2(_wstr, wstr_len)
}
} $else { } $else {
return '' return ''
} }
@ -30,14 +34,16 @@ pub fn string_from_wide(_wstr &u16) string {
pub fn string_from_wide2(_wstr &u16, len int) string { pub fn string_from_wide2(_wstr &u16, len int) string {
$if windows { $if windows {
unsafe {
num_chars := C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, 0, 0, 0, 0) num_chars := C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, 0, 0, 0, 0)
mut str_to := malloc(num_chars + 1) mut str_to := malloc(num_chars + 1)
if str_to != 0 { if str_to != 0 {
C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, charptr(str_to), num_chars, C.WideCharToMultiByte(cp_utf8, 0, _wstr, len, charptr(str_to), num_chars,
0, 0) 0, 0)
unsafe {C.memset(str_to + num_chars, 0, 1)} C.memset(str_to + num_chars, 0, 1)
} }
return tos2(str_to) return tos2(str_to)
}
} $else { } $else {
return '' return ''
} }

View File

@ -10,10 +10,13 @@ pub fn utf8_char_len(b byte) int {
// Convert utf32 to utf8 // Convert utf32 to utf8
// utf32 == Codepoint // utf32 == Codepoint
pub fn utf32_to_str(code u32) string { pub fn utf32_to_str(code u32) string {
unsafe {
mut buffer := malloc(5) mut buffer := malloc(5)
return utf32_to_str_no_malloc(code, buffer) return utf32_to_str_no_malloc(code, buffer)
}
} }
[unsafe]
pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string { pub fn utf32_to_str_no_malloc(code u32, buf voidptr) string {
icode := int(code) // Prevents doing casts everywhere icode := int(code) // Prevents doing casts everywhere
mut res := '' mut res := ''

View File

@ -25,7 +25,7 @@ pub fn read(bytes_needed int) ?[]byte {
} }
rbytes := getrandom(batch_size, bstart) rbytes := getrandom(batch_size, bstart)
if rbytes == -1 { if rbytes == -1 {
free(buffer) unsafe { free(buffer) }
return read_error return read_error
} }
bytes_read += rbytes bytes_read += rbytes

View File

@ -15,7 +15,7 @@ const (
// read returns an array of `bytes_needed` random bytes read from the OS. // read returns an array of `bytes_needed` random bytes read from the OS.
pub fn read(bytes_needed int) ?[]byte { pub fn read(bytes_needed int) ?[]byte {
mut buffer := malloc(bytes_needed) mut buffer := unsafe {malloc(bytes_needed)}
// use bcrypt_use_system_preferred_rng because we passed null as algo // use bcrypt_use_system_preferred_rng because we passed null as algo
status := C.BCryptGenRandom(0, buffer, bytes_needed, bcrypt_use_system_preferred_rng) status := C.BCryptGenRandom(0, buffer, bytes_needed, bcrypt_use_system_preferred_rng)
if status != status_success { if status != status_success {

View File

@ -21,8 +21,10 @@ pub fn decode(data string) string {
if size <= 0 { if size <= 0 {
return '' return ''
} }
unsafe {
buffer := malloc(size) buffer := malloc(size)
return tos(buffer, decode_in_buffer(data, buffer)) return tos(buffer, decode_in_buffer(data, buffer))
}
} }
// encode encodes the `string` value passed in `data` to base64. // encode encodes the `string` value passed in `data` to base64.
@ -34,8 +36,10 @@ pub fn encode(data string) string {
if size <= 0 { if size <= 0 {
return '' return ''
} }
unsafe {
buffer := malloc(size) buffer := malloc(size)
return tos(buffer, encode_in_buffer(data, buffer)) return tos(buffer, encode_in_buffer(data, buffer))
}
} }
// decode_url returns a decoded URL `string` version of // decode_url returns a decoded URL `string` version of

View File

@ -165,7 +165,7 @@ fn utf8util_char_len(b byte) int {
// up_low make the dirt job // up_low make the dirt job
fn up_low(s string, upper_flag bool) string { fn up_low(s string, upper_flag bool) string {
mut index := 0 mut index := 0
mut str_res := malloc(s.len + 1) mut str_res := unsafe {malloc(s.len + 1)}
for { for {
ch_len := utf8util_char_len(s[index]) ch_len := utf8util_char_len(s[index])
@ -289,11 +289,9 @@ fn up_low(s string, upper_flag bool) string {
// for c compatibility set the ending 0 // for c compatibility set the ending 0
unsafe { unsafe {
str_res[index] = 0 str_res[index] = 0
}
//C.printf("str_res: %s\n--------------\n",str_res) //C.printf("str_res: %s\n--------------\n",str_res)
return tos(str_res, s.len) return tos(str_res, s.len)
}
} }
// find_char_in_table utility function for up_low, search utf8 chars in the conversion table // find_char_in_table utility function for up_low, search utf8 chars in the conversion table

View File

@ -125,9 +125,11 @@ pub fn (conn &Connection) tables(wildcard string) ?[]string {
// The `s` argument is encoded to produce an escaped SQL string, // The `s` argument is encoded to produce an escaped SQL string,
// taking into account the current character set of the connection. // taking into account the current character set of the connection.
pub fn (conn &Connection) escape_string(s string) string { pub fn (conn &Connection) escape_string(s string) string {
unsafe {
to := malloc(2 * s.len + 1) to := malloc(2 * s.len + 1)
C.mysql_real_escape_string_quote(conn.conn, to, s.str, s.len, `\'`) C.mysql_real_escape_string_quote(conn.conn, to, s.str, s.len, `\'`)
return unsafe { to.vstring() } return to.vstring()
}
} }
// set_option - sets extra connect options that affect the behavior of // set_option - sets extra connect options that affect the behavior of

View File

@ -11,7 +11,7 @@ fn C.new_tls_context() C.TlsContext
fn (req &Request) ssl_do(port int, method Method, host_name string, path string) ?Response { fn (req &Request) ssl_do(port int, method Method, host_name string, path string) ?Response {
mut ctx := C.new_tls_context() mut ctx := C.new_tls_context()
C.vschannel_init(&ctx) C.vschannel_init(&ctx)
mut buff := malloc(C.vsc_init_resp_buff_size) mut buff := unsafe {malloc(C.vsc_init_resp_buff_size)}
addr := host_name addr := host_name
sdata := req.build_request_headers(method, host_name, path) sdata := req.build_request_headers(method, host_name, path)
length := int(C.request(&ctx, port, addr.to_wide(), sdata.str, &buff)) length := int(C.request(&ctx, port, addr.to_wide(), sdata.str, &buff))

View File

@ -161,7 +161,7 @@ pub fn (c &TcpConn) peer_ip() ?string {
if cstr == 0 { if cstr == 0 {
return error('net.peer_ip: inet_ntop failed') return error('net.peer_ip: inet_ntop failed')
} }
res := cstring_to_vstring(cstr) res := unsafe {cstring_to_vstring(cstr)}
return res return res
} }

View File

@ -12,6 +12,7 @@ fn C.FreeEnvironmentStringsW(&u16) int
// `getenv` returns the value of the environment variable named by the key. // `getenv` returns the value of the environment variable named by the key.
pub fn getenv(key string) string { pub fn getenv(key string) string {
unsafe {
$if windows { $if windows {
s := C._wgetenv(key.to_wide()) s := C._wgetenv(key.to_wide())
if s == 0 { if s == 0 {
@ -26,6 +27,7 @@ pub fn getenv(key string) string {
// NB: C.getenv *requires* that the result be copied. // NB: C.getenv *requires* that the result be copied.
return cstring_to_vstring(byteptr(s)) return cstring_to_vstring(byteptr(s))
} }
}
} }
// os.setenv sets the value of an environment variable with `name` to `value`. // os.setenv sets the value of an environment variable with `name` to `value`.

View File

@ -36,14 +36,14 @@ pub fn fd_slurp(fd int) []string {
// read from filedescriptor, don't block // read from filedescriptor, don't block
// return [bytestring,nrbytes] // return [bytestring,nrbytes]
pub fn fd_read(fd int, maxbytes int) (string, int) { pub fn fd_read(fd int, maxbytes int) (string, int) {
unsafe {
mut buf := malloc(maxbytes) mut buf := malloc(maxbytes)
nbytes := C.read(fd, buf, maxbytes) nbytes := C.read(fd, buf, maxbytes)
if nbytes < 0 { if nbytes < 0 {
free(buf) free(buf)
return '', nbytes return '', nbytes
} }
unsafe {
buf[nbytes] = 0 buf[nbytes] = 0
}
return tos(buf, nbytes), nbytes return tos(buf, nbytes), nbytes
}
} }

View File

@ -600,8 +600,10 @@ pub fn resource_abs_path(path string) string {
} }
fp := join_path(base_path, path) fp := join_path(base_path, path)
res := real_path(fp) res := real_path(fp)
unsafe {
fp.free() fp.free()
base_path.free() base_path.free()
}
return res return res
} }

View File

@ -715,22 +715,26 @@ pub fn chdir(path string) {
pub fn getwd() string { pub fn getwd() string {
$if windows { $if windows {
max := 512 // max_path_len * sizeof(wchar_t) max := 512 // max_path_len * sizeof(wchar_t)
unsafe {
buf := &u16(vcalloc(max * 2)) buf := &u16(vcalloc(max * 2))
if C._wgetcwd(buf, max) == 0 { if C._wgetcwd(buf, max) == 0 {
free(buf) free(buf)
return '' return ''
} }
return string_from_wide(buf) return string_from_wide(buf)
}
} $else { } $else {
buf := vcalloc(512) buf := vcalloc(512)
unsafe {
if C.getcwd(charptr(buf), 512) == 0 { if C.getcwd(charptr(buf), 512) == 0 {
free(buf) free(buf)
return '' return ''
} }
res := unsafe { buf.vstring() }.clone() res := buf.vstring().clone()
free(buf) free(buf)
return res return res
} }
}
} }
// real_path returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved. // real_path returns the full absolute path for fpath, with all relative ../../, symlinks and so on resolved.

View File

@ -54,6 +54,7 @@ fn C.symlink(charptr, charptr) int
pub fn uname() Uname { pub fn uname() Uname {
mut u := Uname{} mut u := Uname{}
utsize := sizeof(C.utsname) utsize := sizeof(C.utsname)
unsafe {
x := malloc(int(utsize)) x := malloc(int(utsize))
d := &C.utsname(x) d := &C.utsname(x)
if C.uname(d) == 0 { if C.uname(d) == 0 {
@ -64,6 +65,7 @@ pub fn uname() Uname {
u.machine = cstring_to_vstring(byteptr(d.machine)) u.machine = cstring_to_vstring(byteptr(d.machine))
} }
free(d) free(d)
}
return u return u
} }
@ -166,10 +168,12 @@ pub fn exec(cmd string) ?Result {
} }
buf := [4096]byte{} buf := [4096]byte{}
mut res := strings.new_builder(1024) mut res := strings.new_builder(1024)
unsafe {
for C.fgets(charptr(buf), 4096, f) != 0 { for C.fgets(charptr(buf), 4096, f) != 0 {
bufbp := byteptr(buf) bufbp := byteptr(buf)
res.write_bytes(bufbp, vstrlen(bufbp)) res.write_bytes(bufbp, vstrlen(bufbp))
} }
}
soutput := res.str() soutput := res.str()
// res.free() // res.free()
exit_code := vpclose(f) exit_code := vpclose(f)

View File

@ -262,8 +262,8 @@ pub fn new(port int, cb voidptr) &Picoev {
loop: loop loop: loop
cb: cb cb: cb
date: C.get_date() date: C.get_date()
buf: malloc(max_fds * max_read + 1) buf: unsafe { malloc(max_fds * max_read + 1) }
out: malloc(max_fds * max_write + 1) out: unsafe { malloc(max_fds * max_write + 1) }
} }
C.picoev_add(loop, fd, C.PICOEV_READ, 0, accept_callback, pv) C.picoev_add(loop, fd, C.PICOEV_READ, 0, accept_callback, pv)
go update_date(mut pv) go update_date(mut pv)

View File

@ -143,7 +143,7 @@ const (
// string returns a string of length `len` containing random characters in range `[a-zA-Z]`. // string returns a string of length `len` containing random characters in range `[a-zA-Z]`.
pub fn string(len int) string { pub fn string(len int) string {
mut buf := malloc(len) mut buf := unsafe {malloc(len)}
for i in 0 .. len { for i in 0 .. len {
unsafe { unsafe {
buf[i] = rand.chars[intn(rand.chars.len)] buf[i] = rand.chars[intn(rand.chars.len)]
@ -159,7 +159,7 @@ const (
// hex returns a hexadecimal number of length `len` containing random characters in range `[a-f0-9]`. // hex returns a hexadecimal number of length `len` containing random characters in range `[a-f0-9]`.
pub fn hex(len int) string { pub fn hex(len int) string {
mut buf := malloc(len) mut buf := unsafe {malloc(len)}
for i in 0 .. len { for i in 0 .. len {
unsafe { unsafe {
buf[i] = rand.hex_chars[intn(rand.hex_chars.len)] buf[i] = rand.hex_chars[intn(rand.hex_chars.len)]
@ -174,7 +174,7 @@ const (
// ascii returns a random string of the printable ASCII characters with length `len`. // ascii returns a random string of the printable ASCII characters with length `len`.
pub fn ascii(len int) string { pub fn ascii(len int) string {
mut buf := malloc(len) mut buf := unsafe {malloc(len)}
for i in 0 .. len { for i in 0 .. len {
unsafe { unsafe {
buf[i] = rand.ascii_chars[intn(rand.ascii_chars.len)] buf[i] = rand.ascii_chars[intn(rand.ascii_chars.len)]
@ -187,7 +187,7 @@ pub fn ascii(len int) string {
// See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random) // See https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)
pub fn uuid_v4() string { pub fn uuid_v4() string {
buflen := 36 buflen := 36
mut buf := malloc(37) mut buf := unsafe {malloc(37)}
mut i_buf := 0 mut i_buf := 0
mut x := u64(0) mut x := u64(0)
mut d := byte(0) mut d := byte(0)
@ -219,8 +219,8 @@ pub fn uuid_v4() string {
buf[23] = `-` buf[23] = `-`
buf[14] = `4` buf[14] = `4`
buf[buflen] = 0 buf[buflen] = 0
return buf.vstring_with_len(buflen)
} }
return unsafe { buf.vstring_with_len(buflen) }
} }
const ( const (
@ -240,7 +240,7 @@ pub fn ulid() string {
// ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`. // ulid_at_millisecond does the same as `ulid` but takes a custom Unix millisecond timestamp via `unix_time_milli`.
pub fn ulid_at_millisecond(unix_time_milli u64) string { pub fn ulid_at_millisecond(unix_time_milli u64) string {
buflen := 26 buflen := 26
mut buf := malloc(27) mut buf := unsafe {malloc(27)}
mut t := unix_time_milli mut t := unix_time_milli
mut i := 9 mut i := 9
for i >= 0 { for i >= 0 {
@ -271,6 +271,6 @@ pub fn ulid_at_millisecond(unix_time_milli u64) string {
} }
unsafe { unsafe {
buf[26] = 0 buf[26] = 0
return buf.vstring_with_len(buflen)
} }
return unsafe { buf.vstring_with_len(buflen) }
} }

View File

@ -111,7 +111,7 @@ pub fn new_channel<T>(n u32) &Channel {
fn new_channel_st(n u32, st u32) &Channel { fn new_channel_st(n u32, st u32) &Channel {
wsem := if n > 0 { n } else { 1 } wsem := if n > 0 { n } else { 1 }
rsem := if n > 0 { u32(0) } else { 1 } rsem := if n > 0 { u32(0) } else { 1 }
rbuf := if n > 0 { malloc(int(n * st)) } else { byteptr(0) } rbuf := if n > 0 { unsafe {malloc(int(n * st))} } else { byteptr(0) }
sbuf := if n > 0 { vcalloc(int(n * 2)) } else { byteptr(0) } sbuf := if n > 0 { vcalloc(int(n * 2)) } else { byteptr(0) }
mut ch := &Channel{ mut ch := &Channel{
objsize: st objsize: st

View File

@ -164,12 +164,13 @@ fn (mut ctx Context) termios_setup() ? {
fn get_cursor_position() (int, int) { fn get_cursor_position() (int, int) {
print('\033[6n') print('\033[6n')
mut s := ''
unsafe {
buf := malloc(25) buf := malloc(25)
len := C.read(C.STDIN_FILENO, buf, 24) len := C.read(C.STDIN_FILENO, buf, 24)
unsafe {
buf[len] = 0 buf[len] = 0
s = tos(buf, len)
} }
s := tos(buf, len)
a := s[2..].split(';') a := s[2..].split(';')
if a.len != 2 { if a.len != 2 {
return -1, -1 return -1, -1
@ -186,12 +187,13 @@ fn supports_truecolor() bool {
print('\x1b[48:2:1:2:3m') print('\x1b[48:2:1:2:3m')
// andquery the current color // andquery the current color
print('\x1bP\$qm\x1b\\') print('\x1bP\$qm\x1b\\')
mut s := ''
unsafe {
buf := malloc(25) buf := malloc(25)
len := C.read(C.STDIN_FILENO, buf, 24) len := C.read(C.STDIN_FILENO, buf, 24)
unsafe {
buf[len] = 0 buf[len] = 0
s = tos(buf, len)
} }
s := tos(buf, len)
return '1:2:3' in s return '1:2:3' in s
} }

View File

@ -35,15 +35,12 @@ pub fn parse_rfc2822(s string) ?Time {
} }
pos := months_string.index(fields[2]) or { return error('Invalid time format: $s') } pos := months_string.index(fields[2]) or { return error('Invalid time format: $s') }
mm := pos / 3 + 1 mm := pos / 3 + 1
mut tmstr := byteptr(0)
unsafe { unsafe {
tmstr = malloc(s.len * 2) tmstr := malloc(s.len * 2)
} count := C.snprintf(charptr(tmstr), (s.len * 2), '%s-%02d-%s %s', fields[3].str,
count := unsafe { mm, fields[1].str, fields[4].str)
C.snprintf(charptr(tmstr), (s.len * 2), '%s-%02d-%s %s', fields[3].str, mm, fields[1].str,
fields[4].str)
}
return parse(tos(tmstr, count)) return parse(tos(tmstr, count))
}
} }
// ----- iso8601 ----- // ----- iso8601 -----

View File

@ -1872,8 +1872,8 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
if f.is_deprecated { if f.is_deprecated {
c.warn('function `$f.name` has been deprecated', call_expr.pos) c.warn('function `$f.name` has been deprecated', call_expr.pos)
} }
if f.is_unsafe && !c.inside_unsafe && f.language == .c && f.name[2] in [`m`, `s`] if f.is_unsafe && !c.inside_unsafe
&& f.mod == 'builtin' { && (f.language != .c || (f.name[2] in [`m`, `s`] && f.mod == 'builtin')) {
// builtin C.m*, C.s* only - temp // builtin C.m*, C.s* only - temp
c.warn('function `$f.name` must be called from an `unsafe` block', call_expr.pos) c.warn('function `$f.name` must be called from an `unsafe` block', call_expr.pos)
} }

View File

@ -132,7 +132,7 @@ pub fn (mut ctx Context) send_response_to_client(mimetype string, res string) bo
} }
s := sb.str() s := sb.str()
defer { defer {
s.free() unsafe { s.free() }
} }
send_string(mut ctx.conn, s) or { return false } send_string(mut ctx.conn, s) or { return false }
return true return true
@ -439,7 +439,7 @@ fn handle_conn<T>(mut conn net.TcpConn, mut app T) {
return return
} }
app.send_response_to_client(mime_type, data) app.send_response_to_client(mime_type, data)
data.free() unsafe { data.free() }
return return
} }
app.init() app.init()

View File

@ -87,7 +87,7 @@ fn (mut bmp BitMap) format_texture() {
// write out a .ppm file // write out a .ppm file
pub fn (mut bmp BitMap) save_as_ppm(file_name string) { pub fn (mut bmp BitMap) save_as_ppm(file_name string) {
tmp_buf := bmp.buf tmp_buf := bmp.buf
mut buf := malloc(bmp.buf_size) mut buf := unsafe {malloc(bmp.buf_size)}
unsafe { C.memcpy(buf, tmp_buf, bmp.buf_size) } unsafe { C.memcpy(buf, tmp_buf, bmp.buf_size) }
bmp.buf = buf bmp.buf = buf
@ -108,7 +108,9 @@ pub fn (mut bmp BitMap) save_as_ppm(file_name string) {
} }
f_out.close() f_out.close()
unsafe {
free(buf) free(buf)
}
bmp.buf = tmp_buf bmp.buf = tmp_buf
} }

View File

@ -53,10 +53,10 @@ pub fn (mut tf_skl TTF_render_Sokol) create_text(in_txt string, in_font_size f32
// RAM buffer // RAM buffer
if sz > tf_skl.bmp.buf_size { if sz > tf_skl.bmp.buf_size {
if sz > 0 { if sz > 0 {
free(tf_skl.bmp.buf) unsafe {free(tf_skl.bmp.buf)}
} }
dprintln('create_text Alloc: $sz bytes') dprintln('create_text Alloc: $sz bytes')
tf_skl.bmp.buf = malloc(sz) tf_skl.bmp.buf = unsafe {malloc(sz)}
tf_skl.bmp.buf_size = sz tf_skl.bmp.buf_size = sz
} }
@ -91,10 +91,10 @@ pub fn (mut tf_skl TTF_render_Sokol) create_text_block(in_txt string, in_w int,
// RAM buffer // RAM buffer
if sz > tf_skl.bmp.buf_size { if sz > tf_skl.bmp.buf_size {
if sz > 0 { if sz > 0 {
free(tf_skl.bmp.buf) unsafe {free(tf_skl.bmp.buf)}
} }
dprintln('Alloc: $sz bytes') dprintln('Alloc: $sz bytes')
tf_skl.bmp.buf = malloc(sz) tf_skl.bmp.buf = unsafe {malloc(sz)}
tf_skl.bmp.buf_size = sz tf_skl.bmp.buf_size = sz
} }

View File

@ -25,7 +25,7 @@ fn (mut ws Client) handshake() ? {
sb.write('\r\nSec-WebSocket-Version: 13\r\n\r\n') sb.write('\r\nSec-WebSocket-Version: 13\r\n\r\n')
handshake := sb.str() handshake := sb.str()
defer { defer {
handshake.free() unsafe { handshake.free() }
} }
handshake_bytes := handshake.bytes() handshake_bytes := handshake.bytes()
ws.debug_log('sending handshake: $handshake') ws.debug_log('sending handshake: $handshake')

View File

@ -107,7 +107,7 @@ pub fn (mut ws Client) connect() ? {
pub fn (mut ws Client) listen() ? { pub fn (mut ws Client) listen() ? {
mut log := 'Starting client listener, server($ws.is_server)...' mut log := 'Starting client listener, server($ws.is_server)...'
ws.logger.info(log) ws.logger.info(log)
log.free() unsafe { log.free() }
defer { defer {
ws.logger.info('Quit client listener, server($ws.is_server)...') ws.logger.info('Quit client listener, server($ws.is_server)...')
if ws.state == .open { if ws.state == .open {
@ -131,7 +131,7 @@ pub fn (mut ws Client) listen() ? {
.text_frame { .text_frame {
log = 'read: text' log = 'read: text'
ws.debug_log(log) ws.debug_log(log)
log.free() unsafe { log.free() }
ws.send_message_event(msg) ws.send_message_event(msg)
unsafe { msg.free() } unsafe { msg.free() }
} }
@ -165,7 +165,7 @@ pub fn (mut ws Client) listen() ? {
.close { .close {
log = 'read: close' log = 'read: close'
ws.debug_log(log) ws.debug_log(log)
log.free() unsafe { log.free() }
defer { defer {
ws.manage_clean_close() ws.manage_clean_close()
} }