all: remove byteptr and charptr; replace them with &byte and &char

pull/9580/head
Alexander Medvednikov 2021-04-04 17:43:32 +03:00
parent 8dd4a63913
commit 57e6138a61
32 changed files with 250 additions and 226 deletions

View File

@ -71,7 +71,7 @@ fn main() {
error_code := C.wkhtmltopdf_http_error_code(converter) error_code := C.wkhtmltopdf_http_error_code(converter)
println('wkhtmltopdf_http_error_code: $error_code') println('wkhtmltopdf_http_error_code: $error_code')
if result { if result {
data := &charptr(0) data := &&char(0)
size := C.wkhtmltopdf_get_output(converter, data) size := C.wkhtmltopdf_get_output(converter, data)
println('wkhtmltopdf_get_output: $size bytes') println('wkhtmltopdf_get_output: $size bytes')
mut file := os.open_file('./google.pdf', 'w+', 0o666) or { mut file := os.open_file('./google.pdf', 'w+', 0o666) or {

View File

@ -166,7 +166,7 @@ pub fn println(s string) {
// malloc returns a `byteptr` pointing to the memory address of the allocated space. // malloc returns a `byteptr` pointing to the memory address of the allocated space.
// unlike the `calloc` family of functions - malloc will not zero the memory block. // unlike the `calloc` family of functions - malloc will not zero the memory block.
[unsafe] [unsafe]
pub fn malloc(n int) byteptr { pub fn malloc(n int) &byte {
if n <= 0 { if n <= 0 {
panic('> V malloc(<=0)') panic('> V malloc(<=0)')
} }
@ -180,7 +180,7 @@ pub fn malloc(n int) byteptr {
C.fprintf(C.stderr, c'v_malloc %6d total %10d\n', n, total_m) C.fprintf(C.stderr, c'v_malloc %6d total %10d\n', n, total_m)
// print_backtrace() // print_backtrace()
} }
mut res := byteptr(0) mut res := &byte(0)
$if prealloc { $if prealloc {
res = g_m2_ptr res = g_m2_ptr
unsafe { unsafe {
@ -216,8 +216,8 @@ fn malloc_size(b byteptr) int
// previously allocated with `malloc`, `v_calloc` or `vcalloc`. // previously allocated with `malloc`, `v_calloc` or `vcalloc`.
// Please, see also realloc_data, and use it instead if possible. // Please, see also realloc_data, and use it instead if possible.
[unsafe] [unsafe]
pub fn v_realloc(b byteptr, n int) byteptr { pub fn v_realloc(b &byte, n int) &byte {
mut new_ptr := byteptr(0) mut new_ptr := &byte(0)
$if prealloc { $if prealloc {
unsafe { unsafe {
new_ptr = malloc(n) new_ptr = malloc(n)
@ -245,7 +245,7 @@ pub fn v_realloc(b byteptr, n int) byteptr {
// can make debugging easier, when you compile your program with // can make debugging easier, when you compile your program with
// `-d debug_realloc`. // `-d debug_realloc`.
[unsafe] [unsafe]
pub fn realloc_data(old_data byteptr, old_size int, new_size int) byteptr { pub fn realloc_data(old_data &byte, old_size int, new_size int) &byte {
$if prealloc { $if prealloc {
unsafe { unsafe {
new_ptr := malloc(new_size) new_ptr := malloc(new_size)
@ -272,7 +272,7 @@ pub fn realloc_data(old_data byteptr, old_size int, new_size int) byteptr {
return new_ptr return new_ptr
} }
} }
mut nptr := byteptr(0) mut nptr := &byte(0)
$if gcboehm ? { $if gcboehm ? {
nptr = unsafe { C.GC_REALLOC(old_data, new_size) } nptr = unsafe { C.GC_REALLOC(old_data, new_size) }
} $else { } $else {
@ -287,14 +287,14 @@ pub fn realloc_data(old_data byteptr, old_size int, new_size 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`.
pub fn vcalloc(n int) byteptr { pub fn vcalloc(n int) &byte {
if n < 0 { if n < 0 {
panic('calloc(<=0)') panic('calloc(<=0)')
} else if n == 0 { } else if n == 0 {
return byteptr(0) return &byte(0)
} }
$if gcboehm ? { $if gcboehm ? {
return byteptr(C.GC_MALLOC(n)) return &byte(C.GC_MALLOC(n))
} $else { } $else {
return C.calloc(1, n) return C.calloc(1, n)
} }

View File

@ -108,7 +108,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
beforeaddr := sframe.all_before('[') beforeaddr := sframe.all_before('[')
cmd := 'addr2line -e $executable $addr' cmd := 'addr2line -e $executable $addr'
// taken from os, to avoid depending on the os module inside builtin.v // taken from os, to avoid depending on the os module inside builtin.v
f := C.popen(charptr(cmd.str), 'r') f := C.popen(&char(cmd.str), c'r')
if isnil(f) { if isnil(f) {
eprintln(sframe) eprintln(sframe)
continue continue
@ -117,7 +117,7 @@ fn print_backtrace_skipping_top_frames_linux(skipframes int) bool {
mut output := '' mut output := ''
unsafe { unsafe {
bp := &buf[0] bp := &buf[0]
for C.fgets(charptr(bp), 1000, f) != 0 { for C.fgets(&char(bp), 1000, f) != 0 {
output += tos(bp, vstrlen(bp)) output += tos(bp, vstrlen(bp))
} }
} }

View File

@ -114,7 +114,7 @@ fn print_backtrace_skipping_top_frames_msvc(skipframes int) bool {
mut si := &sic.syminfo mut si := &sic.syminfo
si.f_size_of_struct = sizeof(SymbolInfo) // Note: C.SYMBOL_INFO is 88 si.f_size_of_struct = sizeof(SymbolInfo) // Note: C.SYMBOL_INFO is 88
si.f_max_name_len = sizeof(SymbolInfoContainer) - sizeof(SymbolInfo) - 1 si.f_max_name_len = sizeof(SymbolInfoContainer) - sizeof(SymbolInfo) - 1
fname := charptr(&si.f_name) fname := &char(&si.f_name)
mut sline64 := Line64{} mut sline64 := Line64{}
sline64.f_size_of_struct = sizeof(Line64) sline64.f_size_of_struct = sizeof(Line64)

View File

@ -23,7 +23,7 @@ fn C.qsort(base voidptr, items size_t, item_size size_t, cb qsort_callback_func)
fn C.sprintf(a ...voidptr) int fn C.sprintf(a ...voidptr) int
fn C.strlen(s charptr) int fn C.strlen(s &char) int
fn C.sscanf(byteptr, byteptr, ...byteptr) int fn C.sscanf(byteptr, byteptr, ...byteptr) int
@ -31,19 +31,19 @@ fn C.sscanf(byteptr, byteptr, ...byteptr) int
fn C.isdigit(c int) bool fn C.isdigit(c int) bool
// stdio.h // stdio.h
fn C.popen(c charptr, t charptr) voidptr fn C.popen(c &char, t &char) voidptr
// <execinfo.h> // <execinfo.h>
fn C.backtrace(a &voidptr, size int) int fn C.backtrace(a &voidptr, size int) int
fn C.backtrace_symbols(a &voidptr, size int) &charptr fn C.backtrace_symbols(a &voidptr, size int) &&char
fn C.backtrace_symbols_fd(a &voidptr, size int, fd int) fn C.backtrace_symbols_fd(a &voidptr, size int, fd int)
// <libproc.h> // <libproc.h>
pub fn proc_pidpath(int, voidptr, int) int pub fn proc_pidpath(int, voidptr, int) int
fn C.realpath(charptr, charptr) &char fn C.realpath(&char, &char) &char
// fn C.chmod(byteptr, mode_t) int // fn C.chmod(byteptr, mode_t) int
fn C.chmod(byteptr, u32) int fn C.chmod(byteptr, u32) int
@ -59,7 +59,7 @@ fn C.fflush(&C.FILE) int
// TODO define args in these functions // TODO define args in these functions
fn C.fseek(stream &C.FILE, offset int, whence int) int fn C.fseek(stream &C.FILE, offset int, whence int) int
fn C.fopen(filename charptr, mode charptr) &C.FILE fn C.fopen(filename &char, mode &char) &C.FILE
fn C.fileno(&C.FILE) int fn C.fileno(&C.FILE) int
@ -75,13 +75,13 @@ fn C.pclose(stream &C.FILE) int
[trusted] [trusted]
fn C.getpid() int fn C.getpid() int
fn C.system(cmd charptr) int fn C.system(cmd &char) int
fn C.posix_spawn(child_pid &int, path charptr, file_actions voidptr, attrp voidptr, argv &charptr, envp &charptr) int fn C.posix_spawn(child_pid &int, path &char, file_actions voidptr, attrp voidptr, argv &&char, envp &&char) int
fn C.posix_spawnp(child_pid &int, exefile charptr, file_actions voidptr, attrp voidptr, argv &charptr, envp &charptr) int fn C.posix_spawnp(child_pid &int, exefile &char, file_actions voidptr, attrp voidptr, argv &&char, envp &&char) int
fn C.execve(cmd_path charptr, args voidptr, envs voidptr) int fn C.execve(cmd_path &char, args voidptr, envs voidptr) int
fn C.execvp(cmd_path charptr, args &charptr) int fn C.execvp(cmd_path charptr, args &charptr) int
@ -99,34 +99,34 @@ fn C.waitpid(pid int, status &int, options int) int
[trusted] [trusted]
fn C.kill(pid int, sig int) int fn C.kill(pid int, sig int) int
fn C.setenv(charptr, charptr, int) int fn C.setenv(&char, &char, int) int
fn C.unsetenv(charptr) int fn C.unsetenv(&char) int
fn C.access(path charptr, amode int) int fn C.access(path &char, amode int) int
fn C.remove(filename charptr) int fn C.remove(filename &char) int
fn C.rmdir(path charptr) int fn C.rmdir(path &char) int
fn C.chdir(path charptr) int fn C.chdir(path &char) int
fn C.rewind(stream &C.FILE) int fn C.rewind(stream &C.FILE) int
fn C.stat(charptr, voidptr) int fn C.stat(&char, voidptr) int
fn C.lstat(path charptr, buf &C.stat) int fn C.lstat(path &char, buf &C.stat) int
fn C.rename(old_filename charptr, new_filename charptr) int fn C.rename(old_filename &char, new_filename &char) int
fn C.fgets(str charptr, n int, stream &C.FILE) int fn C.fgets(str &char, n int, stream &C.FILE) int
fn C.memset(str voidptr, c int, n size_t) int fn C.memset(str voidptr, c int, n size_t) int
[trusted] [trusted]
fn C.sigemptyset() int fn C.sigemptyset() int
fn C.getcwd(buf charptr, size size_t) charptr fn C.getcwd(buf &char, size size_t) &char
fn C.signal(signal int, handlercb voidptr) voidptr fn C.signal(signal int, handlercb voidptr) voidptr
@ -142,12 +142,12 @@ fn C.sleep(seconds u32) u32
[trusted] [trusted]
fn C.usleep(usec u32) int fn C.usleep(usec u32) int
fn C.opendir(charptr) voidptr fn C.opendir(&char) voidptr
fn C.closedir(dirp &C.DIR) int fn C.closedir(dirp &C.DIR) int
// fn C.mkdir(path charptr, mode mode_t) int // fn C.mkdir(path &char, mode mode_t) int
fn C.mkdir(path charptr, mode u32) int fn C.mkdir(path &char, mode u32) int
// C.rand returns a pseudorandom integer from 0 (inclusive) to C.RAND_MAX (exclusive) // C.rand returns a pseudorandom integer from 0 (inclusive) to C.RAND_MAX (exclusive)
[trusted] [trusted]
@ -157,7 +157,7 @@ fn C.rand() int
[trusted] [trusted]
fn C.srand(seed u32) fn C.srand(seed u32)
fn C.atof(str charptr) f64 fn C.atof(str &char) f64
[trusted] [trusted]
fn C.tolower(c int) int fn C.tolower(c int) int
@ -169,9 +169,9 @@ fn C.toupper(c int) int
fn C.getchar() int fn C.getchar() int
[trusted] [trusted]
fn C.strerror(int) charptr fn C.strerror(int) &char
fn C.snprintf(str charptr, size size_t, format charptr, opt ...voidptr) int fn C.snprintf(str &char, size size_t, format &char, opt ...voidptr) int
fn C.fprintf(byteptr, ...byteptr) fn C.fprintf(byteptr, ...byteptr)
@ -240,7 +240,7 @@ fn C.RegSetValueExW(hKey voidptr, lpValueName &u16, Reserved u32, dwType u32, lp
fn C.RegCloseKey(hKey voidptr) fn C.RegCloseKey(hKey voidptr)
fn C.RemoveDirectory(lpPathName charptr) int fn C.RemoveDirectory(lpPathName &char) int
// fn C.GetStdHandle() voidptr // fn C.GetStdHandle() voidptr
fn C.GetStdHandle(u32) voidptr fn C.GetStdHandle(u32) voidptr
@ -257,15 +257,15 @@ fn C.GetCurrentProcessId() int
fn C.wprintf() fn C.wprintf()
// fn C.setbuf() // fn C.setbuf()
fn C.setbuf(voidptr, charptr) fn C.setbuf(voidptr, &char)
fn C.SymCleanup(hProcess voidptr) fn C.SymCleanup(hProcess voidptr)
fn C.MultiByteToWideChar(codePage u32, dwFlags u32, lpMultiMyteStr charptr, cbMultiByte int, lpWideCharStr &u16, cchWideChar int) int fn C.MultiByteToWideChar(codePage u32, dwFlags u32, lpMultiMyteStr &char, cbMultiByte int, lpWideCharStr &u16, cchWideChar int) int
fn C.wcslen(str &u16) int fn C.wcslen(str &u16) int
fn C.WideCharToMultiByte(codePage u32, dwFlags u32, lpWideCharStr &u16, cchWideChar int, lpMultiByteStr charptr, cbMultiByte int, lpDefaultChar charptr, lpUsedDefaultChar &int) int fn C.WideCharToMultiByte(codePage u32, dwFlags u32, lpWideCharStr &u16, cchWideChar int, lpMultiByteStr &char, cbMultiByte int, lpDefaultChar &char, lpUsedDefaultChar &int) int
fn C._wstat(path &u16, buffer &C._stat) fn C._wstat(path &u16, buffer &C._stat)
@ -281,7 +281,7 @@ fn C._wsystem(command &u16) int
fn C._wgetenv(varname &u16) voidptr fn C._wgetenv(varname &u16) voidptr
fn C._putenv(envstring charptr) int fn C._putenv(envstring &char) int
fn C._waccess(path &u16, mode int) int fn C._waccess(path &u16, mode int) int

View File

@ -138,7 +138,7 @@ pub fn (s string) i16() i16 {
// f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`. // f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`.
pub fn (s string) f32() f32 { pub fn (s string) f32() f32 {
// return C.atof(charptr(s.str)) // return C.atof(&char(s.str))
return f32(JS.parseFloat(s)) return f32(JS.parseFloat(s))
} }

View File

@ -102,8 +102,8 @@ mut:
// array allocated (with `cap` bytes) on first deletion // array allocated (with `cap` bytes) on first deletion
// has non-zero element when key deleted // has non-zero element when key deleted
all_deleted &byte all_deleted &byte
values byteptr values &byte
keys byteptr keys &byte
} }
[inline] [inline]
@ -335,7 +335,7 @@ fn new_map_2(key_bytes int, value_bytes int, hash_fn MapHashFn, key_eq_fn MapEqF
cached_hashbits: max_cached_hashbits cached_hashbits: max_cached_hashbits
shift: init_log_capicity shift: init_log_capicity
key_values: new_dense_array(key_bytes, value_bytes) key_values: new_dense_array(key_bytes, value_bytes)
metas: &u32(vcalloc(metasize)) metas: unsafe { &u32(vcalloc(metasize)) }
extra_metas: extra_metas_inc extra_metas: extra_metas_inc
len: 0 len: 0
has_string_keys: has_string_keys has_string_keys: has_string_keys
@ -423,7 +423,7 @@ fn (mut m map) ensure_extra_metas(probe_count u32) {
m.extra_metas += extra_metas_inc m.extra_metas += extra_metas_inc
mem_size := (m.even_index + 2 + m.extra_metas) mem_size := (m.even_index + 2 + m.extra_metas)
unsafe { unsafe {
x := realloc_data(byteptr(m.metas), int(size_of_u32 * old_mem_size), int(size_of_u32 * mem_size)) x := realloc_data(&byte(m.metas), int(size_of_u32 * old_mem_size), int(size_of_u32 * mem_size))
m.metas = &u32(x) m.metas = &u32(x)
C.memset(m.metas + mem_size - extra_metas_inc, 0, int(sizeof(u32) * extra_metas_inc)) C.memset(m.metas + mem_size - extra_metas_inc, 0, int(sizeof(u32) * extra_metas_inc))
} }
@ -463,7 +463,7 @@ fn (mut m map) set_1(key voidptr, value voidptr) {
pkey := m.key_values.key(kv_index) pkey := m.key_values.key(kv_index)
pvalue := m.key_values.value(kv_index) pvalue := m.key_values.value(kv_index)
m.clone_fn(pkey, key) m.clone_fn(pkey, key)
C.memcpy(byteptr(pvalue), value, m.value_bytes) C.memcpy(&byte(pvalue), value, m.value_bytes)
} }
m.meta_greater(index, meta, u32(kv_index)) m.meta_greater(index, meta, u32(kv_index))
m.len++ m.len++
@ -493,7 +493,7 @@ fn (mut m map) rehash() {
meta_bytes := sizeof(u32) * (m.even_index + 2 + m.extra_metas) meta_bytes := sizeof(u32) * (m.even_index + 2 + m.extra_metas)
unsafe { unsafe {
// TODO: use realloc_data here too // TODO: use realloc_data here too
x := v_realloc(byteptr(m.metas), int(meta_bytes)) x := v_realloc(&byte(m.metas), int(meta_bytes))
m.metas = &u32(x) m.metas = &u32(x)
C.memset(m.metas, 0, meta_bytes) C.memset(m.metas, 0, meta_bytes)
} }
@ -513,7 +513,7 @@ fn (mut m map) rehash() {
fn (mut m map) cached_rehash(old_cap u32) { fn (mut m map) cached_rehash(old_cap u32) {
old_metas := m.metas old_metas := m.metas
metasize := int(sizeof(u32) * (m.even_index + 2 + m.extra_metas)) metasize := int(sizeof(u32) * (m.even_index + 2 + m.extra_metas))
m.metas = &u32(vcalloc(metasize)) m.metas = unsafe { &u32(vcalloc(metasize)) }
old_extra_metas := m.extra_metas old_extra_metas := m.extra_metas
for i := u32(0); i <= old_cap + old_extra_metas; i += 2 { for i := u32(0); i <= old_cap + old_extra_metas; i += 2 {
if unsafe { old_metas[i] } == 0 { if unsafe { old_metas[i] } == 0 {
@ -543,7 +543,7 @@ fn (mut m map) get_and_set_1(key voidptr, zero voidptr) voidptr {
pkey := unsafe { m.key_values.key(kv_index) } pkey := unsafe { m.key_values.key(kv_index) }
if m.key_eq_fn(key, pkey) { if m.key_eq_fn(key, pkey) {
pval := unsafe { m.key_values.value(kv_index) } pval := unsafe { m.key_values.value(kv_index) }
return unsafe { byteptr(pval) } return unsafe { &byte(pval) }
} }
} }
index += 2 index += 2
@ -570,7 +570,7 @@ fn (m &map) get_1(key voidptr, zero voidptr) voidptr {
pkey := unsafe { m.key_values.key(kv_index) } pkey := unsafe { m.key_values.key(kv_index) }
if m.key_eq_fn(key, pkey) { if m.key_eq_fn(key, pkey) {
pval := unsafe { m.key_values.value(kv_index) } pval := unsafe { m.key_values.value(kv_index) }
return unsafe { byteptr(pval) } return unsafe { &byte(pval) }
} }
} }
index += 2 index += 2
@ -594,7 +594,7 @@ fn (m &map) get_1_check(key voidptr) voidptr {
pkey := unsafe { m.key_values.key(kv_index) } pkey := unsafe { m.key_values.key(kv_index) }
if m.key_eq_fn(key, pkey) { if m.key_eq_fn(key, pkey) {
pval := unsafe { m.key_values.value(kv_index) } pval := unsafe { m.key_values.value(kv_index) }
return unsafe { byteptr(pval) } return unsafe { &byte(pval) }
} }
} }
index += 2 index += 2

View File

@ -43,8 +43,8 @@ NB: A V string should be/is immutable from the point of view of
*/ */
pub struct string { pub struct string {
pub: pub:
str byteptr // points to a C style 0 terminated string of bytes. str &byte // points to a C style 0 terminated string of bytes.
len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str). len int // the length of the .str field, excluding the ending 0 byte. It is always equal to strlen(.str).
mut: mut:
is_lit int is_lit int
} }
@ -67,14 +67,14 @@ pub mut:
// vstrlen returns the V length of the C string `s` (0 terminator is not counted). // vstrlen returns the V length of the C string `s` (0 terminator is not counted).
[unsafe] [unsafe]
pub fn vstrlen(s byteptr) int { pub fn vstrlen(s &byte) int {
return unsafe { C.strlen(charptr(s)) } return unsafe { C.strlen(&char(s)) }
} }
// 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 &byte, len int) string {
// This should never happen. // This should never happen.
if s == 0 { if s == 0 {
panic('tos(): nil string') panic('tos(): nil string')
@ -87,14 +87,14 @@ pub fn tos(s byteptr, len int) string {
// tos_clone returns a copy of `s`. // tos_clone returns a copy of `s`.
[unsafe] [unsafe]
pub fn tos_clone(s byteptr) string { pub fn tos_clone(s &byte) string {
return unsafe { tos2(s) }.clone() return unsafe { tos2(s) }.clone()
} }
// tos2 does the same as `tos`, but also calculates the length. Called by `string(bytes)` casts. // tos2 does the same as `tos`, but also calculates the length. Called by `string(bytes)` casts.
// Used only internally. // Used only internally.
[unsafe] [unsafe]
pub fn tos2(s byteptr) string { pub fn tos2(s &byte) string {
if s == 0 { if s == 0 {
panic('tos2: nil string') panic('tos2: nil string')
} }
@ -106,19 +106,19 @@ pub fn tos2(s byteptr) string {
// tos3 does the same as `tos2`, but for char*, to avoid warnings. // tos3 does the same as `tos2`, but for char*, to avoid warnings.
[unsafe] [unsafe]
pub fn tos3(s charptr) string { pub fn tos3(s &char) string {
if s == 0 { if s == 0 {
panic('tos3: nil string') panic('tos3: nil string')
} }
return string{ return string{
str: byteptr(s) str: &byte(s)
len: unsafe { C.strlen(s) } len: unsafe { C.strlen(s) }
} }
} }
// tos4 does the same as `tos2`, but returns an empty string on nil ptr. // tos4 does the same as `tos2`, but returns an empty string on nil ptr.
[unsafe] [unsafe]
pub fn tos4(s byteptr) string { pub fn tos4(s &byte) string {
if s == 0 { if s == 0 {
return '' return ''
} }
@ -127,7 +127,7 @@ pub fn tos4(s byteptr) string {
// tos5 does the same as `tos4`, but for char*, to avoid warnings. // tos5 does the same as `tos4`, but for char*, to avoid warnings.
[unsafe] [unsafe]
pub fn tos5(s charptr) string { pub fn tos5(s &char) string {
if s == 0 { if s == 0 {
return '' return ''
} }
@ -135,10 +135,10 @@ pub fn tos5(s charptr) string {
} }
[deprecated] [deprecated]
pub fn tos_lit(s charptr) string { pub fn tos_lit(s &char) string {
eprintln('warning: `tos_lit` has been deprecated, use `_SLIT` instead') eprintln('warning: `tos_lit` has been deprecated, use `_SLIT` instead')
return string{ return string{
str: byteptr(s) str: &byte(s)
len: unsafe { C.strlen(s) } len: unsafe { C.strlen(s) }
is_lit: 1 is_lit: 1
} }
@ -148,17 +148,17 @@ pub fn tos_lit(s charptr) string {
// strings returned from this function will be normal V strings beside that (i.e. they would be // strings returned from this function will be normal V strings beside that (i.e. they would be
// freed by V's -autofree mechanism, when they are no longer used). // freed by V's -autofree mechanism, when they are no longer used).
[unsafe] [unsafe]
pub fn (bp byteptr) vstring() string { pub fn (bp &byte) vstring() string {
return string{ return string{
str: bp str: bp
len: unsafe { C.strlen(charptr(bp)) } len: unsafe { C.strlen(&char(bp)) }
} }
} }
// vstring_with_len converts a C style string to a V string. // vstring_with_len converts a C style string to a V string.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (bp byteptr) vstring_with_len(len int) string { pub fn (bp &byte) vstring_with_len(len int) string {
return string{ return string{
str: bp str: bp
len: len len: len
@ -169,9 +169,9 @@ pub fn (bp byteptr) vstring_with_len(len int) string {
// vstring converts C char* to V string. // vstring converts C char* to V string.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (cp charptr) vstring() string { pub fn (cp &char) vstring() string {
return string{ return string{
str: byteptr(cp) str: &byte(cp)
len: unsafe { C.strlen(cp) } len: unsafe { C.strlen(cp) }
is_lit: 0 is_lit: 0
} }
@ -180,9 +180,9 @@ pub fn (cp charptr) vstring() string {
// vstring_with_len converts C char* to V string. // vstring_with_len converts C char* to V string.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (cp charptr) vstring_with_len(len int) string { pub fn (cp &char) vstring_with_len(len int) string {
return string{ return string{
str: byteptr(cp) str: &byte(cp)
len: len len: len
is_lit: 0 is_lit: 0
} }
@ -196,10 +196,10 @@ pub fn (cp charptr) vstring_with_len(len int) string {
// that can be read by the V program, but that should not be // that can be read by the V program, but that should not be
// managed by it, for example `os.args` is implemented using it. // managed by it, for example `os.args` is implemented using it.
[unsafe] [unsafe]
pub fn (bp byteptr) vstring_literal() string { pub fn (bp &byte) vstring_literal() string {
return string{ return string{
str: bp str: bp
len: unsafe { C.strlen(charptr(bp)) } len: unsafe { C.strlen(&char(bp)) }
is_lit: 1 is_lit: 1
} }
} }
@ -207,7 +207,7 @@ pub fn (bp byteptr) vstring_literal() string {
// vstring_with_len converts a C style string to a V string. // vstring_with_len converts a C style string to a V string.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (bp byteptr) vstring_literal_with_len(len int) string { pub fn (bp &byte) vstring_literal_with_len(len int) string {
return string{ return string{
str: bp str: bp
len: len len: len
@ -219,9 +219,9 @@ pub fn (bp byteptr) vstring_literal_with_len(len int) string {
// See also vstring_literal defined on byteptr for more details. // See also vstring_literal defined on byteptr for more details.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (cp charptr) vstring_literal() string { pub fn (cp &char) vstring_literal() string {
return string{ return string{
str: byteptr(cp) str: &byte(cp)
len: unsafe { C.strlen(cp) } len: unsafe { C.strlen(cp) }
is_lit: 1 is_lit: 1
} }
@ -231,9 +231,9 @@ pub fn (cp charptr) vstring_literal() string {
// See also vstring_literal_with_len defined on byteptr. // See also vstring_literal_with_len defined on byteptr.
// NB: the string data is reused, NOT copied. // NB: the string data is reused, NOT copied.
[unsafe] [unsafe]
pub fn (cp charptr) vstring_literal_with_len(len int) string { pub fn (cp &char) vstring_literal_with_len(len int) string {
return string{ return string{
str: byteptr(cp) str: &byte(cp)
len: len len: len
is_lit: 1 is_lit: 1
} }
@ -270,7 +270,7 @@ pub fn (s string) cstr() byteptr {
*/ */
// cstring_to_vstring creates a copy of cstr and turns it into a v string. // cstring_to_vstring creates a copy of cstr and turns it into a v string.
[unsafe] [unsafe]
pub fn cstring_to_vstring(cstr byteptr) string { pub fn cstring_to_vstring(cstr &byte) string {
return unsafe { tos_clone(cstr) } return unsafe { tos_clone(cstr) }
} }
@ -483,13 +483,13 @@ pub fn (s string) i16() i16 {
// f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`. // f32 returns the value of the string as f32 `'1.0'.f32() == f32(1)`.
pub fn (s string) f32() f32 { pub fn (s string) f32() f32 {
// return C.atof(charptr(s.str)) // return C.atof(&char(s.str))
return f32(strconv.atof64(s)) return f32(strconv.atof64(s))
} }
// f64 returns the value of the string as f64 `'1.0'.f64() == f64(1)`. // f64 returns the value of the string as f64 `'1.0'.f64() == f64(1)`.
pub fn (s string) f64() f64 { pub fn (s string) f64() f64 {
// return C.atof(charptr(s.str)) // return C.atof(&char(s.str))
return strconv.atof64(s) return strconv.atof64(s)
} }
@ -1639,9 +1639,10 @@ pub fn (a []string) join(del string) string {
} }
len -= del.len len -= del.len
// Allocate enough memory // Allocate enough memory
mut res := string{} mut res := string{
res.len = len len: len
res.str = unsafe { malloc(res.len + 1) } str: unsafe { malloc(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 {

View File

@ -553,9 +553,9 @@ fn test_bytes_to_string() {
} }
fn test_charptr() { fn test_charptr() {
foo := charptr('VLANG'.str) foo := &char('VLANG'.str)
println(typeof(foo).name) println(typeof(foo).name)
assert typeof(foo).name == 'charptr' assert typeof(foo).name == '&char'
assert unsafe { foo.vstring() } == 'VLANG' assert unsafe { foo.vstring() } == 'VLANG'
assert unsafe { foo.vstring_with_len(3) } == 'VLA' assert unsafe { foo.vstring_with_len(3) } == 'VLA'
} }

View File

@ -7,11 +7,11 @@ const (
pub fn (_str string) to_wide() &u16 { pub fn (_str string) to_wide() &u16 {
$if windows { $if windows {
unsafe { unsafe {
num_chars := (C.MultiByteToWideChar(cp_utf8, 0, charptr(_str.str), _str.len, num_chars := (C.MultiByteToWideChar(cp_utf8, 0, &char(_str.str), _str.len,
0, 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, &char(_str.str), _str.len, wstr, num_chars)
C.memset(&byte(wstr) + num_chars * 2, 0, 2) C.memset(&byte(wstr) + num_chars * 2, 0, 2)
} }
return wstr return wstr
@ -40,7 +40,7 @@ pub fn string_from_wide2(_wstr &u16, len int) string {
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, &char(str_to), num_chars,
0, 0) 0, 0)
C.memset(str_to + num_chars, 0, 1) C.memset(str_to + num_chars, 0, 1)
} }

View File

@ -17,7 +17,7 @@ fn C.dlerror() charptr
// open loads the dynamic shared object. // open loads the dynamic shared object.
pub fn open(filename string, flags int) voidptr { pub fn open(filename string, flags int) voidptr {
return C.dlopen(charptr(filename.str), flags) return C.dlopen(&char(filename.str), flags)
} }
// close frees a given shared object. // close frees a given shared object.
@ -27,7 +27,7 @@ pub fn close(handle voidptr) bool {
// sym returns an address of a symbol in a given shared object. // sym returns an address of a symbol in a given shared object.
pub fn sym(handle voidptr, symbol string) voidptr { pub fn sym(handle voidptr, symbol string) voidptr {
return C.dlsym(handle, charptr(symbol.str)) return C.dlsym(handle, &char(symbol.str))
} }
// dlerror provides a text error diagnostic message for functions in `dl` // dlerror provides a text error diagnostic message for functions in `dl`

View File

@ -178,13 +178,13 @@ fn encode_bool(val bool) &C.cJSON {
} }
fn encode_string(val string) &C.cJSON { fn encode_string(val string) &C.cJSON {
return C.cJSON_CreateString(charptr(val.str)) return C.cJSON_CreateString(&char(val.str))
} }
// /////////////////////// // ///////////////////////
// user := decode_User(json_parse(js_string_var)) // user := decode_User(json_parse(js_string_var))
fn json_parse(s string) &C.cJSON { fn json_parse(s string) &C.cJSON {
return C.cJSON_Parse(charptr(s.str)) return C.cJSON_Parse(&char(s.str))
} }
// json_string := json_print(encode_User(user)) // json_string := json_print(encode_User(user))

View File

@ -36,7 +36,7 @@ fn new_addr(addr C.sockaddr) ?Addr {
socket_error(-1) ? socket_error(-1) ?
} }
} $else { } $else {
res := charptr(C.inet_ntop(SocketFamily.inet, &addr, buf.data, buf.len)) res := &char(C.inet_ntop(SocketFamily.inet, &addr, buf.data, buf.len))
if res == 0 { if res == 0 {
socket_error(-1) ? socket_error(-1) ?
} }

View File

@ -33,14 +33,14 @@ pub fn (mut c TcpConn) close() ? {
} }
// write_ptr blocks and attempts to write all data // write_ptr blocks and attempts to write all data
pub fn (mut c TcpConn) write_ptr(b byteptr, len int) ?int { pub fn (mut c TcpConn) write_ptr(b &byte, len int) ?int {
$if trace_tcp ? { $if trace_tcp ? {
eprintln( eprintln(
'>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' + '>>> TcpConn.write_ptr | c.sock.handle: $c.sock.handle | b: ${ptr_str(b)} len: $len |\n' +
unsafe { b.vstring_with_len(len) }) unsafe { b.vstring_with_len(len) })
} }
unsafe { unsafe {
mut ptr_base := byteptr(b) mut ptr_base := &byte(b)
mut total_sent := 0 mut total_sent := 0
for total_sent < len { for total_sent < len {
ptr := ptr_base + total_sent ptr := ptr_base + total_sent
@ -77,7 +77,7 @@ pub fn (mut c TcpConn) write_string(s string) ?int {
return c.write_ptr(s.str, s.len) return c.write_ptr(s.str, s.len)
} }
pub fn (mut c TcpConn) read_ptr(buf_ptr byteptr, len int) ?int { pub fn (mut c TcpConn) read_ptr(buf_ptr &byte, len int) ?int {
mut res := wrap_read_result(C.recv(c.sock.handle, buf_ptr, len, 0)) ? mut res := wrap_read_result(C.recv(c.sock.handle, buf_ptr, len, 0)) ?
$if trace_tcp ? { $if trace_tcp ? {
eprintln('<<< TcpConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res') eprintln('<<< TcpConn.read_ptr | c.sock.handle: $c.sock.handle | buf_ptr: ${ptr_str(buf_ptr)} len: $len | res: $res')
@ -163,7 +163,7 @@ pub fn (c &TcpConn) peer_ip() ?string {
peeraddr := C.sockaddr_in{} peeraddr := C.sockaddr_in{}
speeraddr := sizeof(peeraddr) speeraddr := sizeof(peeraddr)
socket_error(C.getpeername(c.sock.handle, unsafe { &C.sockaddr(&peeraddr) }, &speeraddr)) ? socket_error(C.getpeername(c.sock.handle, unsafe { &C.sockaddr(&peeraddr) }, &speeraddr)) ?
cstr := charptr(C.inet_ntop(SocketFamily.inet, &peeraddr.sin_addr, &buf[0], sizeof(buf))) cstr := &char(C.inet_ntop(SocketFamily.inet, &peeraddr.sin_addr, &buf[0], sizeof(buf)))
if cstr == 0 { if cstr == 0 {
return error('net.peer_ip: inet_ntop failed') return error('net.peer_ip: inet_ntop failed')
} }

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module os module os
fn C.getenv(charptr) &char fn C.getenv(&char) &char
// C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows // C.GetEnvironmentStringsW & C.FreeEnvironmentStringsW are defined only on windows
fn C.GetEnvironmentStringsW() &u16 fn C.GetEnvironmentStringsW() &u16
@ -20,12 +20,12 @@ pub fn getenv(key string) string {
} }
return string_from_wide(s) return string_from_wide(s)
} $else { } $else {
s := C.getenv(charptr(key.str)) s := C.getenv(&char(key.str))
if s == voidptr(0) { if s == voidptr(0) {
return '' return ''
} }
// 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(&byte(s))
} }
} }
} }
@ -36,19 +36,19 @@ pub fn setenv(name string, value string, overwrite bool) int {
format := '$name=$value' format := '$name=$value'
if overwrite { if overwrite {
unsafe { unsafe {
return C._putenv(charptr(format.str)) return C._putenv(&char(format.str))
} }
} else { } else {
if getenv(name).len == 0 { if getenv(name).len == 0 {
unsafe { unsafe {
return C._putenv(charptr(format.str)) return C._putenv(&char(format.str))
} }
} }
} }
return -1 return -1
} $else { } $else {
unsafe { unsafe {
return C.setenv(charptr(name.str), charptr(value.str), overwrite) return C.setenv(&char(name.str), &char(value.str), overwrite)
} }
} }
} }
@ -57,9 +57,9 @@ pub fn setenv(name string, value string, overwrite bool) int {
pub fn unsetenv(name string) int { pub fn unsetenv(name string) int {
$if windows { $if windows {
format := '$name=' format := '$name='
return C._putenv(charptr(format.str)) return C._putenv(&char(format.str))
} $else { } $else {
return C.unsetenv(charptr(name.str)) return C.unsetenv(&char(name.str))
} }
} }
@ -83,14 +83,18 @@ pub fn environ() map[string]string {
} }
C.FreeEnvironmentStringsW(estrings) C.FreeEnvironmentStringsW(estrings)
} $else { } $else {
/*
// e := unsafe { &&char(C.environ) }
e := unsafe { &charptr(C.environ) } e := unsafe { &charptr(C.environ) }
for i := 0; !isnil(unsafe { e[i] }); i++ { for i := 0; !isnil(unsafe { e[i] }); i++ {
eline := unsafe { cstring_to_vstring(byteptr(e[i])) } x := &byte(e[i])
eline := unsafe { cstring_to_vstring(x) }
eq_index := eline.index_byte(`=`) eq_index := eline.index_byte(`=`)
if eq_index > 0 { if eq_index > 0 {
res[eline[0..eq_index]] = eline[eq_index + 1..] res[eline[0..eq_index]] = eline[eq_index + 1..]
} }
} }
*/
} }
return res return res
} }

View File

@ -57,11 +57,11 @@ pub fn open_file(path string, mode string, options ...int) ?File {
$if windows { $if windows {
p = path.replace('/', '\\') p = path.replace('/', '\\')
} }
fd := C.open(charptr(p.str), flags, permission) fd := C.open(&char(p.str), flags, permission)
if fd == -1 { if fd == -1 {
return error(posix_get_error_msg(C.errno)) return error(posix_get_error_msg(C.errno))
} }
cfile := C.fdopen(fd, charptr(mode.str)) cfile := C.fdopen(fd, &char(mode.str))
if isnil(cfile) { if isnil(cfile) {
return error('Failed to open or create file "$path"') return error('Failed to open or create file "$path"')
} }

View File

@ -32,7 +32,7 @@ pub:
// it supports windows for regular files but it doesn't matter if you use owner, group or others when checking permissions on windows // it supports windows for regular files but it doesn't matter if you use owner, group or others when checking permissions on windows
pub fn inode(path string) FileMode { pub fn inode(path string) FileMode {
mut attr := C.stat{} mut attr := C.stat{}
unsafe { C.stat(charptr(path.str), &attr) } unsafe { C.stat(&char(path.str), &attr) }
mut typ := FileType.regular mut typ := FileType.regular
if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFDIR) { if attr.st_mode & u32(C.S_IFMT) == u32(C.S_IFDIR) {
typ = .directory typ = .directory

View File

@ -9,7 +9,7 @@ struct C.dirent {
fn C.readdir(voidptr) &C.dirent fn C.readdir(voidptr) &C.dirent
fn C.readlink(pathname charptr, buf charptr, bufsiz size_t) int fn C.readlink(pathname &char, buf &char, bufsiz size_t) int
fn C.getline(voidptr, voidptr, voidptr) int fn C.getline(voidptr, voidptr, voidptr) int
@ -17,15 +17,15 @@ fn C.ftell(fp voidptr) int
fn C.sigaction(int, voidptr, int) int fn C.sigaction(int, voidptr, int) int
fn C.open(charptr, int, ...int) int fn C.open(&char, int, ...int) int
fn C.fdopen(fd int, mode charptr) &C.FILE fn C.fdopen(fd int, mode &char) &C.FILE
fn C.CopyFile(&u32, &u32, int) int fn C.CopyFile(&u32, &u32, int) int
// fn C.lstat(charptr, voidptr) u64 // fn C.lstat(charptr, voidptr) u64
fn C._wstat64(charptr, voidptr) u64 fn C._wstat64(&char, voidptr) u64
// fn C.proc_pidpath(int, byteptr, int) int // fn C.proc_pidpath(int, byteptr, int) int
struct C.stat { struct C.stat {
@ -54,7 +54,7 @@ mut:
} }
struct C.dirent { struct C.dirent {
d_name byteptr d_name &byte
} }
// read_bytes returns all bytes read from file in `path`. // read_bytes returns all bytes read from file in `path`.
@ -121,7 +121,7 @@ pub fn file_size(path string) u64 {
C._wstat64(path.to_wide(), voidptr(&swin)) C._wstat64(path.to_wide(), voidptr(&swin))
return swin.st_size return swin.st_size
} $else { } $else {
C.stat(charptr(path.str), &s) C.stat(&char(path.str), &s)
return u64(s.st_size) return u64(s.st_size)
} }
} }
@ -133,7 +133,7 @@ pub fn file_size(path string) u64 {
C._wstat(path.to_wide(), voidptr(&s)) C._wstat(path.to_wide(), voidptr(&s))
return u64(s.st_size) return u64(s.st_size)
} $else { } $else {
C.stat(charptr(path.str), &s) C.stat(&char(path.str), &s)
return u64(s.st_size) return u64(s.st_size)
} }
} }
@ -155,7 +155,7 @@ pub fn mv(src string, dst string) ? {
return error_with_code('failed to rename $src to $dst', int(ret)) return error_with_code('failed to rename $src to $dst', int(ret))
} }
} $else { } $else {
ret := C.rename(charptr(src.str), charptr(rdst.str)) ret := C.rename(&char(src.str), &char(rdst.str))
if ret != 0 { if ret != 0 {
return error_with_code('failed to rename $src to $dst', int(ret)) return error_with_code('failed to rename $src to $dst', int(ret))
} }
@ -172,11 +172,11 @@ pub fn cp(src string, dst string) ? {
return error_with_code('failed to copy $src to $dst', int(result)) return error_with_code('failed to copy $src to $dst', int(result))
} }
} $else { } $else {
fp_from := C.open(charptr(src.str), C.O_RDONLY) fp_from := C.open(&char(src.str), C.O_RDONLY)
if fp_from < 0 { // Check if file opened if fp_from < 0 { // Check if file opened
return error_with_code('cp: failed to open $src', int(fp_from)) return error_with_code('cp: failed to open $src', int(fp_from))
} }
fp_to := C.open(charptr(dst.str), C.O_WRONLY | C.O_CREAT | C.O_TRUNC, C.S_IWUSR | C.S_IRUSR) fp_to := C.open(&char(dst.str), C.O_WRONLY | C.O_CREAT | C.O_TRUNC, C.S_IWUSR | C.S_IRUSR)
if fp_to < 0 { // Check if file opened (permissions problems ...) if fp_to < 0 { // Check if file opened (permissions problems ...)
C.close(fp_from) C.close(fp_from)
return error_with_code('cp (permission): failed to write to $dst (fp_to: $fp_to)', return error_with_code('cp (permission): failed to write to $dst (fp_to: $fp_to)',
@ -197,9 +197,9 @@ pub fn cp(src string, dst string) ? {
} }
from_attr := C.stat{} from_attr := C.stat{}
unsafe { unsafe {
C.stat(charptr(src.str), &from_attr) C.stat(&char(src.str), &from_attr)
} }
if C.chmod(charptr(dst.str), from_attr.st_mode) < 0 { if C.chmod(&char(dst.str), from_attr.st_mode) < 0 {
return error_with_code('failed to set permissions for $dst', int(-1)) return error_with_code('failed to set permissions for $dst', int(-1))
} }
C.close(fp_to) C.close(fp_to)
@ -218,7 +218,7 @@ pub fn vfopen(path string, mode string) ?&C.FILE {
$if windows { $if windows {
fp = C._wfopen(path.to_wide(), mode.to_wide()) fp = C._wfopen(path.to_wide(), mode.to_wide())
} $else { } $else {
fp = C.fopen(charptr(path.str), charptr(mode.str)) fp = C.fopen(&char(path.str), &char(mode.str))
} }
if isnil(fp) { if isnil(fp) {
return error('failed to open file "$path"') return error('failed to open file "$path"')
@ -249,7 +249,7 @@ fn vpopen(path string) voidptr {
return C._wpopen(wpath, mode.to_wide()) return C._wpopen(wpath, mode.to_wide())
} $else { } $else {
cpath := path.str cpath := path.str
return C.popen(charptr(cpath), 'r') return C.popen(&char(cpath), c'r')
} }
} }
@ -306,7 +306,7 @@ pub fn system(cmd string) int {
} $else { } $else {
$if ios { $if ios {
unsafe { unsafe {
arg := [c'/bin/sh', c'-c', byteptr(cmd.str), 0] arg := [c'/bin/sh', c'-c', &byte(cmd.str), 0]
pid := 0 pid := 0
ret = C.posix_spawn(&pid, '/bin/sh', 0, 0, arg.data, 0) ret = C.posix_spawn(&pid, '/bin/sh', 0, 0, arg.data, 0)
status := 0 status := 0
@ -317,7 +317,7 @@ pub fn system(cmd string) int {
} }
} $else { } $else {
unsafe { unsafe {
ret = C.system(charptr(cmd.str)) ret = C.system(&char(cmd.str))
} }
} }
} }
@ -340,7 +340,7 @@ pub fn exists(path string) bool {
p := path.replace('/', '\\') p := path.replace('/', '\\')
return C._waccess(p.to_wide(), f_ok) != -1 return C._waccess(p.to_wide(), f_ok) != -1
} $else { } $else {
return C.access(charptr(path.str), f_ok) != -1 return C.access(&char(path.str), f_ok) != -1
} }
} }
@ -359,13 +359,13 @@ pub fn is_executable(path string) bool {
$if solaris { $if solaris {
statbuf := C.stat{} statbuf := C.stat{}
unsafe { unsafe {
if C.stat(charptr(path.str), &statbuf) != 0 { if C.stat(&char(path.str), &statbuf) != 0 {
return false return false
} }
} }
return (int(statbuf.st_mode) & (s_ixusr | s_ixgrp | s_ixoth)) != 0 return (int(statbuf.st_mode) & (s_ixusr | s_ixgrp | s_ixoth)) != 0
} }
return C.access(charptr(path.str), x_ok) != -1 return C.access(&char(path.str), x_ok) != -1
} }
// is_writable returns `true` if `path` is writable. // is_writable returns `true` if `path` is writable.
@ -374,7 +374,7 @@ pub fn is_writable(path string) bool {
p := path.replace('/', '\\') p := path.replace('/', '\\')
return C._waccess(p.to_wide(), w_ok) != -1 return C._waccess(p.to_wide(), w_ok) != -1
} $else { } $else {
return C.access(charptr(path.str), w_ok) != -1 return C.access(&char(path.str), w_ok) != -1
} }
} }
@ -384,7 +384,7 @@ pub fn is_readable(path string) bool {
p := path.replace('/', '\\') p := path.replace('/', '\\')
return C._waccess(p.to_wide(), r_ok) != -1 return C._waccess(p.to_wide(), r_ok) != -1
} $else { } $else {
return C.access(charptr(path.str), r_ok) != -1 return C.access(&char(path.str), r_ok) != -1
} }
} }
@ -394,7 +394,7 @@ pub fn rm(path string) ? {
$if windows { $if windows {
rc = C._wremove(path.to_wide()) rc = C._wremove(path.to_wide())
} $else { } $else {
rc = C.remove(charptr(path.str)) rc = C.remove(&char(path.str))
} }
if rc == -1 { if rc == -1 {
return error('Failed to remove "$path": ' + posix_get_error_msg(C.errno)) return error('Failed to remove "$path": ' + posix_get_error_msg(C.errno))
@ -411,7 +411,7 @@ pub fn rmdir(path string) ? {
return error('Failed to remove "$path": ' + posix_get_error_msg(C.errno)) return error('Failed to remove "$path": ' + posix_get_error_msg(C.errno))
} }
} $else { } $else {
rc := C.rmdir(charptr(path.str)) rc := C.rmdir(&char(path.str))
if rc == -1 { if rc == -1 {
return error(posix_get_error_msg(C.errno)) return error(posix_get_error_msg(C.errno))
} }
@ -421,7 +421,7 @@ pub fn rmdir(path string) ? {
// print_c_errno will print the current value of `C.errno`. // print_c_errno will print the current value of `C.errno`.
fn print_c_errno() { fn print_c_errno() {
e := C.errno e := C.errno
se := unsafe { tos_clone(byteptr(C.strerror(C.errno))) } se := unsafe { tos_clone(&byte(C.strerror(C.errno))) }
println('errno=$e err=$se') println('errno=$e err=$se')
} }
@ -460,9 +460,9 @@ pub fn get_raw_line() string {
} }
} $else { } $else {
max := size_t(0) max := size_t(0)
buf := charptr(0) buf := &char(0)
nr_chars := unsafe { C.getline(&buf, &max, C.stdin) } nr_chars := unsafe { C.getline(&buf, &max, C.stdin) }
return unsafe { tos(byteptr(buf), if nr_chars < 0 { 0 } else { nr_chars }) } return unsafe { tos(&byte(buf), if nr_chars < 0 { 0 } else { nr_chars }) }
} }
} }
@ -496,7 +496,7 @@ pub fn get_raw_stdin() []byte {
} }
} $else { } $else {
max := size_t(0) max := size_t(0)
buf := charptr(0) buf := &char(0)
nr_chars := unsafe { C.getline(&buf, &max, C.stdin) } nr_chars := unsafe { C.getline(&buf, &max, C.stdin) }
return array{ return array{
element_size: 1 element_size: 1
@ -554,7 +554,7 @@ pub fn on_segfault(f voidptr) {
pub fn executable() string { pub fn executable() string {
$if linux { $if linux {
mut xresult := vcalloc(max_path_len) mut xresult := vcalloc(max_path_len)
count := C.readlink('/proc/self/exe', charptr(xresult), max_path_len) count := C.readlink('/proc/self/exe', &char(xresult), max_path_len)
if count < 0 { if count < 0 {
eprintln('os.executable() failed at reading /proc/self/exe to get exe path') eprintln('os.executable() failed at reading /proc/self/exe to get exe path')
return executable_fallback() return executable_fallback()
@ -616,7 +616,7 @@ pub fn executable() string {
} }
$if netbsd { $if netbsd {
mut result := vcalloc(max_path_len) mut result := vcalloc(max_path_len)
count := C.readlink('/proc/curproc/exe', charptr(result), max_path_len) count := C.readlink('/proc/curproc/exe', &char(result), max_path_len)
if count < 0 { if count < 0 {
eprintln('os.executable() failed at reading /proc/curproc/exe to get exe path') eprintln('os.executable() failed at reading /proc/curproc/exe to get exe path')
return executable_fallback() return executable_fallback()
@ -625,7 +625,7 @@ pub fn executable() string {
} }
$if dragonfly { $if dragonfly {
mut result := vcalloc(max_path_len) mut result := vcalloc(max_path_len)
count := C.readlink('/proc/curproc/file', charptr(result), max_path_len) count := C.readlink('/proc/curproc/file', &char(result), max_path_len)
if count < 0 { if count < 0 {
eprintln('os.executable() failed at reading /proc/curproc/file to get exe path') eprintln('os.executable() failed at reading /proc/curproc/file to get exe path')
return executable_fallback() return executable_fallback()
@ -649,7 +649,7 @@ pub fn is_dir(path string) bool {
return false return false
} $else { } $else {
statbuf := C.stat{} statbuf := C.stat{}
if unsafe { C.stat(charptr(path.str), &statbuf) } != 0 { if unsafe { C.stat(&char(path.str), &statbuf) } != 0 {
return false return false
} }
// ref: https://code.woboq.org/gcc/include/sys/stat.h.html // ref: https://code.woboq.org/gcc/include/sys/stat.h.html
@ -664,7 +664,7 @@ pub fn is_link(path string) bool {
return false // TODO return false // TODO
} $else { } $else {
statbuf := C.stat{} statbuf := C.stat{}
if C.lstat(charptr(path.str), &statbuf) != 0 { if C.lstat(&char(path.str), &statbuf) != 0 {
return false return false
} }
return int(statbuf.st_mode) & s_ifmt == s_iflnk return int(statbuf.st_mode) & s_ifmt == s_iflnk
@ -676,7 +676,7 @@ pub fn chdir(path string) {
$if windows { $if windows {
C._wchdir(path.to_wide()) C._wchdir(path.to_wide())
} $else { } $else {
C.chdir(charptr(path.str)) C.chdir(&char(path.str))
} }
} }
@ -695,7 +695,7 @@ pub fn getwd() string {
} $else { } $else {
buf := vcalloc(512) buf := vcalloc(512)
unsafe { unsafe {
if C.getcwd(charptr(buf), 512) == 0 { if C.getcwd(&char(buf), 512) == 0 {
free(buf) free(buf)
return '' return ''
} }
@ -713,7 +713,7 @@ pub fn getwd() string {
// NB: this particular rabbit hole is *deep* ... // NB: this particular rabbit hole is *deep* ...
[manualfree] [manualfree]
pub fn real_path(fpath string) string { pub fn real_path(fpath string) string {
mut fullpath := byteptr(0) mut fullpath := &byte(0)
defer { defer {
unsafe { free(fullpath) } unsafe { free(fullpath) }
} }
@ -727,7 +727,7 @@ pub fn real_path(fpath string) string {
} }
} $else { } $else {
fullpath = vcalloc(max_path_len) fullpath = vcalloc(max_path_len)
ret := charptr(C.realpath(charptr(fpath.str), charptr(fullpath))) ret := &char(C.realpath(&char(fpath.str), &char(fullpath)))
if ret == 0 { if ret == 0 {
return fpath return fpath
} }
@ -796,7 +796,7 @@ pub fn wait() int {
pub fn file_last_mod_unix(path string) int { pub fn file_last_mod_unix(path string) int {
attr := C.stat{} attr := C.stat{}
// # struct stat attr; // # struct stat attr;
unsafe { C.stat(charptr(path.str), &attr) } unsafe { C.stat(&char(path.str), &attr) }
// # stat(path.str, &attr); // # stat(path.str, &attr);
return attr.st_mtime return attr.st_mtime
// # return attr.st_mtime ; // # return attr.st_mtime ;
@ -810,7 +810,7 @@ pub fn flush() {
// chmod change file access attributes of `path` to `mode`. // chmod change file access attributes of `path` to `mode`.
// Octals like `0o600` can be used. // Octals like `0o600` can be used.
pub fn chmod(path string, mode int) { pub fn chmod(path string, mode int) {
C.chmod(charptr(path.str), mode) C.chmod(&char(path.str), mode)
} }
// open_append opens `path` file for appending. // open_append opens `path` file for appending.
@ -825,7 +825,7 @@ pub fn open_append(path string) ?File {
} $else { } $else {
cpath := path.str cpath := path.str
file = File{ file = File{
cfile: C.fopen(charptr(cpath), 'ab') cfile: C.fopen(&char(cpath), c'ab')
} }
} }
if isnil(file.cfile) { if isnil(file.cfile) {
@ -841,17 +841,17 @@ pub fn open_append(path string) ?File {
// NB: this function will NOT return when successfull, since // NB: this function will NOT return when successfull, since
// the child process will take control over execution. // the child process will take control over execution.
pub fn execvp(cmdpath string, args []string) ? { pub fn execvp(cmdpath string, args []string) ? {
mut cargs := []charptr{} mut cargs := []&char{}
cargs << charptr(cmdpath.str) cargs << &char(cmdpath.str)
for i in 0 .. args.len { for i in 0 .. args.len {
cargs << charptr(args[i].str) cargs << &char(args[i].str)
} }
cargs << charptr(0) cargs << &char(0)
mut res := int(0) mut res := int(0)
$if windows { $if windows {
res = C._execvp(charptr(cmdpath.str), cargs.data) res = C._execvp(&char(cmdpath.str), cargs.data)
} $else { } $else {
res = C.execvp(charptr(cmdpath.str), cargs.data) res = C.execvp(&char(cmdpath.str), cargs.data)
} }
if res == -1 { if res == -1 {
return error_with_code(posix_get_error_msg(C.errno), C.errno) return error_with_code(posix_get_error_msg(C.errno), C.errno)
@ -867,22 +867,22 @@ pub fn execvp(cmdpath string, args []string) ? {
// NB: this function will NOT return when successfull, since // NB: this function will NOT return when successfull, since
// the child process will take control over execution. // the child process will take control over execution.
pub fn execve(cmdpath string, args []string, envs []string) ? { pub fn execve(cmdpath string, args []string, envs []string) ? {
mut cargv := []charptr{} mut cargv := []&char{}
mut cenvs := []charptr{} mut cenvs := []&char{}
cargv << charptr(cmdpath.str) cargv << &char(cmdpath.str)
for i in 0 .. args.len { for i in 0 .. args.len {
cargv << charptr(args[i].str) cargv << &char(args[i].str)
} }
for i in 0 .. envs.len { for i in 0 .. envs.len {
cenvs << charptr(envs[i].str) cenvs << &char(envs[i].str)
} }
cargv << charptr(0) cargv << &char(0)
cenvs << charptr(0) cenvs << &char(0)
mut res := int(0) mut res := int(0)
$if windows { $if windows {
res = C._execve(charptr(cmdpath.str), cargv.data, cenvs.data) res = C._execve(&char(cmdpath.str), cargv.data, cenvs.data)
} $else { } $else {
res = C.execve(charptr(cmdpath.str), cargv.data, cenvs.data) res = C.execve(&char(cmdpath.str), cargv.data, cenvs.data)
} }
// NB: normally execve does not return at all. // NB: normally execve does not return at all.
// If it returns, then something went wrong... // If it returns, then something went wrong...

View File

@ -75,14 +75,14 @@ fn init_os_args(argc int, argv &&byte) []string {
// mut args := []string{len:argc} // mut args := []string{len:argc}
for i in 0 .. argc { for i in 0 .. argc {
// args [i] = argv[i].vstring() // args [i] = argv[i].vstring()
unsafe { args_ << byteptr(argv[i]).vstring_literal() } unsafe { args_ << (&byte(argv[i])).vstring_literal() }
} }
return args_ return args_
} }
pub fn ls(path string) ?[]string { pub fn ls(path string) ?[]string {
mut res := []string{} mut res := []string{}
dir := unsafe { C.opendir(charptr(path.str)) } dir := unsafe { C.opendir(&char(path.str)) }
if isnil(dir) { if isnil(dir) {
return error('ls() couldnt open dir "$path"') return error('ls() couldnt open dir "$path"')
} }
@ -149,7 +149,7 @@ pub fn mkdir(path string) ?bool {
} }
} }
*/ */
r := unsafe { C.mkdir(charptr(apath.str), 511) } r := unsafe { C.mkdir(&char(apath.str), 511) }
if r == -1 { if r == -1 {
return error(posix_get_error_msg(C.errno)) return error(posix_get_error_msg(C.errno))
} }
@ -177,7 +177,7 @@ pub fn execute(cmd string) Result {
} }
unsafe { unsafe {
bufbp := &buf[0] bufbp := &buf[0]
for C.fgets(charptr(bufbp), 4096, f) != 0 { for C.fgets(&char(bufbp), 4096, f) != 0 {
res.write_ptr(bufbp, vstrlen(bufbp)) res.write_ptr(bufbp, vstrlen(bufbp))
} }
} }
@ -220,7 +220,7 @@ pub fn (mut c Command) read_line() string {
} }
unsafe { unsafe {
bufbp := &buf[0] bufbp := &buf[0]
for C.fgets(charptr(bufbp), 4096, c.f) != 0 { for C.fgets(&char(bufbp), 4096, c.f) != 0 {
len := vstrlen(bufbp) len := vstrlen(bufbp)
for i in 0 .. len { for i in 0 .. len {
if bufbp[i] == `\n` { if bufbp[i] == `\n` {
@ -245,7 +245,7 @@ pub fn (c &Command) close() ? {
} }
pub fn symlink(origin string, target string) ?bool { pub fn symlink(origin string, target string) ?bool {
res := C.symlink(charptr(origin.str), charptr(target.str)) res := C.symlink(&char(origin.str), &char(target.str))
if res == 0 { if res == 0 {
return true return true
} }
@ -290,7 +290,7 @@ pub fn is_writable_folder(folder string) ?bool {
} }
tmp_perm_check := join_path(folder, 'XXXXXX') tmp_perm_check := join_path(folder, 'XXXXXX')
unsafe { unsafe {
x := C.mkstemp(charptr(tmp_perm_check.str)) x := C.mkstemp(&char(tmp_perm_check.str))
if -1 == x { if -1 == x {
return error('folder `$folder` is not writable') return error('folder `$folder` is not writable')
} }
@ -309,7 +309,7 @@ pub fn getpid() int {
pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) { pub fn posix_set_permission_bit(path_s string, mode u32, enable bool) {
mut s := C.stat{} mut s := C.stat{}
mut new_mode := u32(0) mut new_mode := u32(0)
path := charptr(path_s.str) path := &char(path_s.str)
unsafe { unsafe {
C.stat(path, &s) C.stat(path, &s)
new_mode = s.st_mode new_mode = s.st_mode

View File

@ -522,7 +522,7 @@ fn test_posix_set_bit() {
fpath := '/tmp/permtest' fpath := '/tmp/permtest'
create(fpath) or { panic("Couldn't create file") } create(fpath) or { panic("Couldn't create file") }
chmod(fpath, 0o7777) chmod(fpath, 0o7777)
c_fpath := charptr(fpath.str) c_fpath := &char(fpath.str)
mut s := C.stat{} mut s := C.stat{}
unsafe { unsafe {
C.stat(c_fpath, &s) C.stat(c_fpath, &s)

View File

@ -28,13 +28,13 @@ pub fn new_builder(initial_size int) Builder {
[deprecated: 'use Builder.write_ptr() instead'] [deprecated: 'use Builder.write_ptr() instead']
[deprecated_after: '2021-04-18'] [deprecated_after: '2021-04-18']
[unsafe] [unsafe]
pub fn (mut b Builder) write_bytes(bytes byteptr, len int) { pub fn (mut b Builder) write_bytes(bytes &byte, len int) {
unsafe { b.write_ptr(bytes, len) } unsafe { b.write_ptr(bytes, len) }
} }
// write_ptr writes `len` bytes provided byteptr to the accumulated buffer // write_ptr writes `len` bytes provided byteptr to the accumulated buffer
[unsafe] [unsafe]
pub fn (mut b Builder) write_ptr(ptr byteptr, len int) { pub fn (mut b Builder) write_ptr(ptr &byte, len int) {
unsafe { b.buf.push_many(ptr, len) } unsafe { b.buf.push_many(ptr, len) }
b.len += len b.len += len
} }
@ -140,7 +140,7 @@ pub fn (b &Builder) after(n int) string {
// .str() call. // .str() call.
pub fn (mut b Builder) str() string { pub fn (mut b Builder) str() string {
b.buf << `\0` b.buf << `\0`
s := unsafe { byteptr(memdup(b.buf.data, b.len)).vstring_with_len(b.len) } s := unsafe { (&byte(memdup(b.buf.data, b.len))).vstring_with_len(b.len) }
b.len = 0 b.len = 0
b.buf.trim(0) b.buf.trim(0)
return s return s

View File

@ -208,7 +208,7 @@ pub fn extract_zip_to_dir(file string, dir string) ?bool {
if C.access(dir.str, 0) == -1 { if C.access(dir.str, 0) == -1 {
return error('szip: cannot open directory for extracting, directory not exists') return error('szip: cannot open directory for extracting, directory not exists')
} }
res := C.zip_extract_without_callback(charptr(file.str), charptr(dir.str)) res := C.zip_extract_without_callback(&char(file.str), &char(dir.str))
return res == 0 return res == 0
} }

View File

@ -37,7 +37,7 @@ pub fn parse_rfc2822(s string) ?Time {
mm := pos / 3 + 1 mm := pos / 3 + 1
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 := C.snprintf(&char(tmstr), (s.len * 2), c'%s-%02d-%s %s', fields[3].str,
mm, fields[1].str, fields[4].str) mm, fields[1].str, fields[4].str)
return parse(tos(tmstr, count)) return parse(tos(tmstr, count))
} }
@ -50,7 +50,7 @@ const (
fn parse_iso8601_date(s string) ?(int, int, int) { fn parse_iso8601_date(s string) ?(int, int, int) {
year, month, day, dummy := 0, 0, 0, byte(0) year, month, day, dummy := 0, 0, 0, byte(0)
count := unsafe { C.sscanf(charptr(s.str), '%4d-%2d-%2d%c', &year, &month, &day, &dummy) } count := unsafe { C.sscanf(&char(s.str), '%4d-%2d-%2d%c', &year, &month, &day, &dummy) }
if count != 3 { if count != 3 {
return time.err_invalid_8601 return time.err_invalid_8601
} }
@ -66,14 +66,14 @@ fn parse_iso8601_time(s string) ?(int, int, int, int, i64, bool) {
offset_hour := 0 offset_hour := 0
offset_minute := 0 offset_minute := 0
mut count := unsafe { mut count := unsafe {
C.sscanf(charptr(s.str), '%2d:%2d:%2d.%6d%c%2d:%2d', &hour_, &minute_, &second_, C.sscanf(&char(s.str), '%2d:%2d:%2d.%6d%c%2d:%2d', &hour_, &minute_, &second_,
&microsecond_, charptr(&plus_min_z), &offset_hour, &offset_minute) &microsecond_, &char(&plus_min_z), &offset_hour, &offset_minute)
} }
// Missread microsecond ([Sec Hour Minute].len == 3 < 4) // Missread microsecond ([Sec Hour Minute].len == 3 < 4)
if count < 4 { if count < 4 {
count = unsafe { count = unsafe {
C.sscanf(charptr(s.str), '%2d:%2d:%2d%c%2d:%2d', &hour_, &minute_, &second_, C.sscanf(&char(s.str), '%2d:%2d:%2d%c%2d:%2d', &hour_, &minute_, &second_,
charptr(&plus_min_z), &offset_hour, &offset_minute) &char(&plus_min_z), &offset_hour, &offset_minute)
} }
count++ // Increment count because skipped microsecond count++ // Increment count because skipped microsecond
} }

View File

@ -882,6 +882,7 @@ pub fn (t &Table) sumtype_has_variant(parent Type, variant Type) bool {
return false return false
} }
// only used for debugging V compiler type bugs
pub fn (t &Table) known_type_names() []string { pub fn (t &Table) known_type_names() []string {
mut res := []string{cap: t.type_idxs.len} mut res := []string{cap: t.type_idxs.len}
for _, idx in t.type_idxs { for _, idx in t.type_idxs {

View File

@ -813,8 +813,14 @@ pub fn (mytable &Table) type_to_code(t Type) string {
} }
// import_aliases is a map of imported symbol aliases 'module.Type' => 'Type' // import_aliases is a map of imported symbol aliases 'module.Type' => 'Type'
pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[string]string) string { pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string]string) string {
sym := mytable.get_type_symbol(t) /*
if t.pref.is_verbose {
print_backtrace()
exit(0)
}
*/
sym := t.get_type_symbol(typ)
mut res := sym.name mut res := sym.name
match sym.kind { match sym.kind {
.int_literal, .float_literal { .int_literal, .float_literal {
@ -823,23 +829,29 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str
.i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .char, .rune, .string, .bool, .i8, .i16, .int, .i64, .byte, .u16, .u32, .u64, .f32, .f64, .char, .rune, .string, .bool,
.none_, .byteptr, .voidptr, .charptr { .none_, .byteptr, .voidptr, .charptr {
// primitive types // primitive types
res = sym.kind.str() if sym.kind == .byteptr {
res = '&byte'
} else if sym.kind == .charptr {
res = '&char'
} else {
res = sym.kind.str()
}
} }
.array { .array {
if t == ast.array_type { if typ == ast.array_type {
return 'array' return 'array'
} }
if t.has_flag(.variadic) { if typ.has_flag(.variadic) {
res = mytable.type_to_str_using_aliases(mytable.value_type(t), import_aliases) res = t.type_to_str_using_aliases(t.value_type(typ), import_aliases)
} else { } else {
info := sym.info as Array info := sym.info as Array
elem_str := mytable.type_to_str_using_aliases(info.elem_type, import_aliases) elem_str := t.type_to_str_using_aliases(info.elem_type, import_aliases)
res = '[]$elem_str' res = '[]$elem_str'
} }
} }
.array_fixed { .array_fixed {
info := sym.info as ArrayFixed info := sym.info as ArrayFixed
elem_str := mytable.type_to_str_using_aliases(info.elem_type, import_aliases) elem_str := t.type_to_str_using_aliases(info.elem_type, import_aliases)
res = '[$info.size]$elem_str' res = '[$info.size]$elem_str'
} }
.chan { .chan {
@ -852,63 +864,63 @@ pub fn (mytable &Table) type_to_str_using_aliases(t Type, import_aliases map[str
mut_str = 'mut ' mut_str = 'mut '
elem_type = elem_type.set_nr_muls(elem_type.nr_muls() - 1) elem_type = elem_type.set_nr_muls(elem_type.nr_muls() - 1)
} }
elem_str := mytable.type_to_str_using_aliases(elem_type, import_aliases) elem_str := t.type_to_str_using_aliases(elem_type, import_aliases)
res = 'chan $mut_str$elem_str' res = 'chan $mut_str$elem_str'
} }
} }
.function { .function {
info := sym.info as FnType info := sym.info as FnType
if !mytable.is_fmt { if !t.is_fmt {
res = mytable.fn_signature(info.func, type_only: true) res = t.fn_signature(info.func, type_only: true)
} else { } else {
if res.starts_with('fn (') { if res.starts_with('fn (') {
// fn foo () // fn foo ()
res = mytable.fn_signature(info.func, type_only: true) res = t.fn_signature(info.func, type_only: true)
} else { } else {
// FnFoo // FnFoo
res = mytable.shorten_user_defined_typenames(res, import_aliases) res = t.shorten_user_defined_typenames(res, import_aliases)
} }
} }
} }
.map { .map {
if int(t) == ast.map_type_idx { if int(typ) == ast.map_type_idx {
return 'map' return 'map'
} }
info := sym.info as Map info := sym.info as Map
key_str := mytable.type_to_str_using_aliases(info.key_type, import_aliases) key_str := t.type_to_str_using_aliases(info.key_type, import_aliases)
val_str := mytable.type_to_str_using_aliases(info.value_type, import_aliases) val_str := t.type_to_str_using_aliases(info.value_type, import_aliases)
res = 'map[$key_str]$val_str' res = 'map[$key_str]$val_str'
} }
.multi_return { .multi_return {
res = '(' res = '('
info := sym.info as MultiReturn info := sym.info as MultiReturn
for i, typ in info.types { for i, typ2 in info.types {
if i > 0 { if i > 0 {
res += ', ' res += ', '
} }
res += mytable.type_to_str_using_aliases(typ, import_aliases) res += t.type_to_str_using_aliases(typ2, import_aliases)
} }
res += ')' res += ')'
} }
.void { .void {
if t.has_flag(.optional) { if typ.has_flag(.optional) {
return '?' return '?'
} }
return 'void' return 'void'
} }
else { else {
res = mytable.shorten_user_defined_typenames(res, import_aliases) res = t.shorten_user_defined_typenames(res, import_aliases)
} }
} }
mut nr_muls := t.nr_muls() mut nr_muls := typ.nr_muls()
if t.has_flag(.shared_f) { if typ.has_flag(.shared_f) {
nr_muls-- nr_muls--
res = 'shared ' + res res = 'shared ' + res
} }
if nr_muls > 0 { if nr_muls > 0 {
res = strings.repeat(`&`, nr_muls) + res res = strings.repeat(`&`, nr_muls) + res
} }
if t.has_flag(.optional) { if typ.has_flag(.optional) {
res = '?' + res res = '?' + res
} }
return res return res

View File

@ -241,7 +241,8 @@ pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
if exp_idx == got_idx { if exp_idx == got_idx {
return true return true
} }
if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx { if exp_idx == ast.voidptr_type_idx || exp_idx == ast.byteptr_type_idx
|| (expected.is_ptr() && expected.deref().idx() == ast.byte_type_idx) {
if got.is_ptr() || got.is_pointer() { if got.is_ptr() || got.is_pointer() {
return true return true
} }
@ -253,7 +254,8 @@ pub fn (mut c Checker) check_types(got ast.Type, expected ast.Type) bool {
return true return true
} }
} }
if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx { if got_idx == ast.voidptr_type_idx || got_idx == ast.byteptr_type_idx
|| (got_idx == ast.byte_type_idx && got.is_ptr()) {
if expected.is_ptr() || expected.is_pointer() { if expected.is_ptr() || expected.is_pointer() {
return true return true
} }

View File

@ -2915,7 +2915,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
c.error('cannot modify blank `_` identifier', left.pos) c.error('cannot modify blank `_` identifier', left.pos)
} }
} else if left.info !is ast.IdentVar { } else if left.info !is ast.IdentVar {
c.error('cannot assign to $left.kind `$left.name`', left.pos) c.error('1cannot assign to $left.kind `$left.name`', left.pos)
} else { } else {
if is_decl { if is_decl {
c.check_valid_snake_case(left.name, 'variable name', left.pos) c.check_valid_snake_case(left.name, 'variable name', left.pos)
@ -3019,7 +3019,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
} }
right_is_ptr := right_type.is_ptr() || right_sym.is_pointer() right_is_ptr := right_type.is_ptr() || right_sym.is_pointer()
if !right_is_ptr && assign_stmt.op == .assign && right_type_unwrapped.is_number() { if !right_is_ptr && assign_stmt.op == .assign && right_type_unwrapped.is_number() {
c.error('cannot assign to `$left`: ' + c.error('2cannot assign to `$left`: ' +
c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position()) c.expected_msg(right_type_unwrapped, left_type_unwrapped), right.position())
} }
if (right is ast.StructInit || !right_is_ptr) && !(right_sym.is_number() if (right is ast.StructInit || !right_is_ptr) && !(right_sym.is_number()
@ -3122,7 +3122,7 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
&& left_sym.kind != .interface_ { && left_sym.kind != .interface_ {
// Dual sides check (compatibility check) // Dual sides check (compatibility check)
c.check_expected(right_type_unwrapped, left_type_unwrapped) or { c.check_expected(right_type_unwrapped, left_type_unwrapped) or {
c.error('cannot assign to `$left`: $err.msg', right.position()) c.error('3cannot assign to `$left`: $err.msg', right.position())
} }
} }
if left_sym.kind == .interface_ { if left_sym.kind == .interface_ {
@ -4412,7 +4412,8 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
// variadic case can happen when arrays are converted into variadic // variadic case can happen when arrays are converted into variadic
msg := if node.expr_type.has_flag(.optional) { 'an optional' } else { 'a variadic' } msg := if node.expr_type.has_flag(.optional) { 'an optional' } else { 'a variadic' }
c.error('cannot type cast $msg', node.pos) c.error('cannot type cast $msg', node.pos)
} else if !c.inside_unsafe && node.typ.is_ptr() && node.expr_type.is_ptr() { } else if !c.inside_unsafe && node.typ.is_ptr() && node.expr_type.is_ptr()
&& node.typ.deref() != ast.char_type && node.expr_type.deref() != ast.char_type {
ft := c.table.type_to_str(node.expr_type) ft := c.table.type_to_str(node.expr_type)
tt := c.table.type_to_str(node.typ) tt := c.table.type_to_str(node.typ)
c.warn('casting `$ft` to `$tt` is only allowed in `unsafe` code', node.pos) c.warn('casting `$ft` to `$tt` is only allowed in `unsafe` code', node.pos)
@ -5240,7 +5241,10 @@ pub fn (mut c Checker) lock_expr(mut node ast.LockExpr) ast.Type {
} }
pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type { pub fn (mut c Checker) unsafe_expr(mut node ast.UnsafeExpr) ast.Type {
assert !c.inside_unsafe // assert !c.inside_unsafe
if c.inside_unsafe {
c.error('unsafe inside unsafe', node.pos)
}
c.inside_unsafe = true c.inside_unsafe = true
t := c.expr(node.expr) t := c.expr(node.expr)
c.inside_unsafe = false c.inside_unsafe = false

View File

@ -17,16 +17,16 @@ vlib/v/checker/tests/fixed_array_conv.vv:6:6: error: cannot cast a fixed array (
5 | ip = arr 5 | ip = arr
6 | _ = &int(arr) 6 | _ = &int(arr)
| ~~~~~~~~ | ~~~~~~~~
7 | 7 |
8 | unsafe { 8 | unsafe {
vlib/v/checker/tests/fixed_array_conv.vv:9:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` vlib/v/checker/tests/fixed_array_conv.vv:9:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup`
7 | 7 |
8 | unsafe { 8 | unsafe {
9 | _ = memdup(arr, 1) 9 | _ = memdup(arr, 1)
| ~~~ | ~~~
10 | _ = tos(arr, 1) 10 | _ = tos(arr, 1)
11 | fn (p &int){}(arr) 11 | fn (p &int){}(arr)
vlib/v/checker/tests/fixed_array_conv.vv:10:10: error: cannot use `[2]int` as `byteptr` in argument 1 to `tos` vlib/v/checker/tests/fixed_array_conv.vv:10:10: error: cannot use `[2]int` as `&byte` in argument 1 to `tos`
8 | unsafe { 8 | unsafe {
9 | _ = memdup(arr, 1) 9 | _ = memdup(arr, 1)
10 | _ = tos(arr, 1) 10 | _ = tos(arr, 1)

View File

@ -1,5 +1,5 @@
fn proc_pidpath(int, voidptr, int) int fn proc_pidpath(int, voidptr, int) int
fn C.realpath(charptr, charptr) &char fn C.realpath(&char, &char) &char
fn C.chmod(byteptr, int) int fn C.chmod(&byte, int) int

View File

@ -1 +1 @@
fn C.PQgetvalue(voidptr, int, int) byteptr fn C.PQgetvalue(voidptr, int, int) &byte

View File

@ -666,7 +666,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
if word.len != 2 { if word.len != 2 {
verror('opcodes format: xx xx xx xx') verror('opcodes format: xx xx xx xx')
} }
b := unsafe { C.strtol(charptr(word.str), 0, 16) } b := unsafe { C.strtol(&char(word.str), 0, 16) }
// b := word.byte() // b := word.byte()
// println('"$word" $b') // println('"$word" $b')
g.write8(b) g.write8(b)

View File

@ -50,7 +50,7 @@ pub fn vhash() string {
buf[0] = 0 buf[0] = 0
unsafe { unsafe {
bp := &buf[0] bp := &buf[0]
C.snprintf(charptr(bp), 50, '%s', C.V_COMMIT_HASH) C.snprintf(&char(bp), 50, c'%s', C.V_COMMIT_HASH)
return tos_clone(bp) return tos_clone(bp)
} }
} }
@ -119,7 +119,7 @@ pub fn githash(should_get_from_filesystem bool) string {
buf[0] = 0 buf[0] = 0
unsafe { unsafe {
bp := &buf[0] bp := &buf[0]
C.snprintf(charptr(bp), 50, '%s', C.V_CURRENT_COMMIT_HASH) C.snprintf(&char(bp), 50, c'%s', C.V_CURRENT_COMMIT_HASH)
return tos_clone(bp) return tos_clone(bp)
} }
} }