checker: define missing C fn args & check C & JS args (#8770)

pull/9134/head
joe-conigliaro 2021-03-06 01:41:11 +11:00 committed by GitHub
parent ead2ba6004
commit 2d73411396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
34 changed files with 358 additions and 284 deletions

View File

@ -3283,13 +3283,13 @@ fn C.sqlite3_close(&C.sqlite3) int
fn C.sqlite3_column_int(stmt &C.sqlite3_stmt, n int) int
// ... you can also just define the type of parameter and leave out the C. prefix
fn C.sqlite3_prepare_v2(&sqlite3, charptr, int, &&sqlite3_stmt, &charptr) int
fn C.sqlite3_prepare_v2(&C.sqlite3, charptr, int, &&C.sqlite3_stmt, &charptr) int
fn C.sqlite3_step(&sqlite3_stmt)
fn C.sqlite3_step(&C.sqlite3_stmt)
fn C.sqlite3_finalize(&sqlite3_stmt)
fn C.sqlite3_finalize(&C.sqlite3_stmt)
fn C.sqlite3_exec(db &sqlite3, sql charptr, cb FnSqlite3Callback, cb_arg voidptr, emsg &charptr) int
fn C.sqlite3_exec(db &C.sqlite3, sql charptr, cb FnSqlite3Callback, cb_arg voidptr, emsg &charptr) int
fn C.sqlite3_free(voidptr)

View File

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

View File

@ -45,9 +45,10 @@ pub fn proc_pidpath(int, voidptr, int) int
fn C.realpath(charptr, charptr) &char
fn C.chmod(byteptr, int) int
// fn C.chmod(byteptr, mode_t) int
fn C.chmod(byteptr, u32) int
fn C.printf(byteptr, ...byteptr) int
fn C.printf(byteptr, ...voidptr) int
fn C.puts(byteptr) int
@ -56,7 +57,7 @@ fn C.fputs(str byteptr, stream &C.FILE) int
fn C.fflush(&C.FILE) int
// TODO define args in these functions
fn C.fseek() int
fn C.fseek(stream &C.FILE, offset int, whence int) int
fn C.fopen(filename charptr, mode charptr) &C.FILE
@ -66,9 +67,9 @@ fn C.fread(ptr voidptr, item_size size_t, items size_t, stream &C.FILE) size_t
fn C.fwrite(ptr voidptr, item_size size_t, items size_t, stream &C.FILE) size_t
fn C.fclose() int
fn C.fclose(stream &C.FILE) int
fn C.pclose() int
fn C.pclose(stream &C.FILE) int
// process execution, os.process:
fn C.getpid() int
@ -94,25 +95,25 @@ fn C.setenv(charptr, charptr, int) int
fn C.unsetenv(charptr) int
fn C.access() int
fn C.access(path charptr, amode int) int
fn C.remove() int
fn C.remove(filename charptr) int
fn C.rmdir() int
fn C.rmdir(path charptr) int
fn C.chdir() int
fn C.chdir(path charptr) int
fn C.rewind() int
fn C.rewind(stream &C.FILE) int
fn C.stat(charptr, voidptr) int
fn C.lstat() int
fn C.lstat(path charptr, buf &C.stat) int
fn C.rename() int
fn C.rename(old_filename charptr, new_filename charptr) int
fn C.fgets() int
fn C.fgets(str charptr, n int, stream &C.FILE) int
fn C.memset() int
fn C.memset(str voidptr, c int, n size_t) int
fn C.sigemptyset() int
@ -122,18 +123,20 @@ fn C.signal(signal int, handlercb voidptr) voidptr
fn C.mktime() int
fn C.gettimeofday() int
fn C.gettimeofday(tv &C.timeval, tz &C.timezone) int
[trusted]
fn C.sleep(int) int
fn C.sleep(seconds u32) u32
fn C.usleep() int
// fn C.usleep(usec useconds_t) int
fn C.usleep(usec u32) int
fn C.opendir(charptr) voidptr
fn C.closedir() int
fn C.closedir(dirp &C.DIR) int
fn C.mkdir() int
// fn C.mkdir(path charptr, mode mode_t) int
fn C.mkdir(path charptr, mode u32) int
// C.rand returns a pseudorandom integer from 0 (inclusive) to C.RAND_MAX (exclusive)
[trusted]
@ -141,13 +144,13 @@ fn C.rand() int
// C.srand seeds the internal PRNG with the given value.
[trusted]
fn C.srand(seed uint)
fn C.srand(seed u32)
fn C.atof() int
fn C.atof(str charptr) f64
fn C.tolower() int
fn C.tolower(c int) int
fn C.toupper() int
fn C.toupper(c int) int
[trusted]
fn C.getchar() int
@ -155,33 +158,33 @@ fn C.getchar() int
[trusted]
fn C.strerror(int) charptr
fn C.snprintf() int
fn C.snprintf(str charptr, size size_t, format charptr, opt ...voidptr) int
fn C.fprintf(byteptr, ...byteptr)
fn C.WIFEXITED() bool
fn C.WIFEXITED(status int) bool
fn C.WEXITSTATUS() int
fn C.WEXITSTATUS(status int) int
fn C.WIFSIGNALED() bool
fn C.WIFSIGNALED(status int) bool
fn C.WTERMSIG() int
fn C.WTERMSIG(status int) int
fn C.isatty() int
fn C.isatty(fd int) int
fn C.syscall() int
fn C.syscall(number int, va ...voidptr) int
fn C.sysctl() int
fn C.sysctl(name &int, namelen u32, oldp voidptr, oldlenp voidptr, newp voidptr, newlen size_t) int
fn C._fileno(int) int
fn C._get_osfhandle(fd int) C.intptr_t
fn C.GetModuleFileName() int
fn C.GetModuleFileName(hModule voidptr, lpFilename &u16, nSize u32) int
fn C.GetModuleFileNameW(hModule voidptr, lpFilename &u16, nSize u32) u32
fn C.CreateFile() voidptr
fn C.CreateFile(lpFilename &u16, dwDesiredAccess u32, dwShareMode u32, lpSecurityAttributes &u16, dwCreationDisposition u32, dwFlagsAndAttributes u32, hTemplateFile voidptr) voidptr
fn C.CreateFileW(lpFilename &u16, dwDesiredAccess u32, dwShareMode u32, lpSecurityAttributes &u16, dwCreationDisposition u32, dwFlagsAndAttributes u32, hTemplateFile voidptr) u32
@ -203,11 +206,11 @@ fn C.ReadFile(hFile voidptr, lpBuffer voidptr, nNumberOfBytesToRead u32, lpNumbe
fn C.GetFileAttributesW(lpFileName byteptr) u32
fn C.RegQueryValueEx() voidptr
fn C.RegQueryValueEx(hKey voidptr, lpValueName &u16, lp_reserved &u32, lpType &u32, lpData byteptr, lpcbData &u32) voidptr
fn C.RegQueryValueExW(hKey voidptr, lpValueName &u16, lp_reserved &u32, lpType &u32, lpData byteptr, lpcbData &u32) int
fn C.RegOpenKeyEx() voidptr
fn C.RegOpenKeyEx(hKey voidptr, lpSubKey &u16, ulOptions u32, samDesired u32, phkResult voidptr) voidptr
fn C.RegOpenKeyExW(hKey voidptr, lpSubKey &u16, ulOptions u32, samDesired u32, phkResult voidptr) int
@ -215,9 +218,9 @@ fn C.RegSetValueEx() voidptr
fn C.RegSetValueExW(hKey voidptr, lpValueName &u16, Reserved u32, dwType u32, lpData byteptr, lpcbData u32) int
fn C.RegCloseKey()
fn C.RegCloseKey(hKey voidptr)
fn C.RemoveDirectory() int
fn C.RemoveDirectory(lpPathName charptr) int
// fn C.GetStdHandle() voidptr
fn C.GetStdHandle(u32) voidptr
@ -235,33 +238,33 @@ fn C.wprintf()
// fn C.setbuf()
fn C.setbuf(voidptr, charptr)
fn C.SymCleanup()
fn C.SymCleanup(hProcess voidptr)
fn C.MultiByteToWideChar() int
fn C.MultiByteToWideChar(codePage u32, dwFlags u32, lpMultiMyteStr charptr, cbMultiByte int, lpWideCharStr &u16, cchWideChar int) int
fn C.wcslen() int
fn C.wcslen(str &u16) int
fn C.WideCharToMultiByte() int
fn C.WideCharToMultiByte(codePage u32, dwFlags u32, lpWideCharStr &u16, cchWideChar int, lpMultiByteStr charptr, cbMultiByte int, lpDefaultChar charptr, lpUsedDefaultChar &int) int
fn C._wstat()
fn C._wstat(path &u16, buffer &C._stat)
fn C._wrename() int
fn C._wrename(oldname &u16, newname &u16) int
fn C._wfopen() voidptr
fn C._wfopen(filename &u16, mode &u16) voidptr
fn C._wpopen() voidptr
fn C._wpopen(command &u16, mode &u16) voidptr
fn C._pclose() int
fn C._pclose(stream &C.FILE) int
fn C._wsystem() int
fn C._wsystem(command &u16) int
fn C._wgetenv() voidptr
fn C._wgetenv(varname &u16) voidptr
fn C._putenv() int
fn C._putenv(envstring charptr) int
fn C._waccess() int
fn C._waccess(path &u16, mode int) int
fn C._wremove() int
fn C._wremove(path &u16) int
fn C.ReadConsole(in_input_handle voidptr, out_buffer voidptr, in_chars_to_read u32, out_read_chars &u32, in_input_control voidptr) bool
@ -269,9 +272,9 @@ fn C.WriteConsole() voidptr
fn C.WriteFile() voidptr
fn C._wchdir()
fn C._wchdir(dirname &u16)
fn C._wgetcwd() int
fn C._wgetcwd(buffer &u16, maxlen int) int
fn C._fullpath() int
@ -281,25 +284,26 @@ fn C.GetCommandLine() voidptr
fn C.LocalFree()
fn C.FindFirstFileW() voidptr
fn C.FindFirstFileW(lpFileName &u16, lpFindFileData voidptr) voidptr
fn C.FindFirstFile() voidptr
fn C.FindFirstFile(lpFileName byteptr, lpFindFileData voidptr) voidptr
fn C.FindNextFile() int
fn C.FindNextFile(hFindFile voidptr, lpFindFileData voidptr) int
fn C.FindClose()
fn C.FindClose(hFindFile voidptr)
fn C.MAKELANGID() int
// macro
fn C.MAKELANGID(lgid voidptr, srtid voidptr) int
fn C.FormatMessage() voidptr
fn C.FormatMessage(dwFlags u32, lpSource voidptr, dwMessageId u32, dwLanguageId u32, lpBuffer voidptr, nSize int, Arguments ...voidptr) voidptr
fn C.CloseHandle(voidptr) int
fn C.GetExitCodeProcess()
fn C.GetExitCodeProcess(hProcess voidptr, lpExitCode &u32)
fn C.GetTickCount() i64
fn C.Sleep()
fn C.Sleep(dwMilliseconds u32)
fn C.WSAStartup(u16, &voidptr) int

View File

@ -20,7 +20,7 @@ struct WndClassEx {
h_icon_sm &u16
}
fn C.RegisterClassEx(class WndClassEx) int
fn C.RegisterClassEx(class &WndClassEx) int
fn C.GetClipboardOwner() &C.HWND
@ -35,9 +35,9 @@ fn C.GlobalAlloc(uFlag u32, size i64) C.HGLOBAL
fn C.GlobalFree(buf C.HGLOBAL)
fn C.GlobalLock(buf C.HGLOBAL)
fn C.GlobalLock(buf C.HGLOBAL) voidptr
fn C.GlobalUnlock(buf C.HGLOBAL)
fn C.GlobalUnlock(buf C.HGLOBAL) bool
fn C.SetClipboardData(uFormat u32, data voidptr) C.HANDLE
@ -174,8 +174,8 @@ pub fn (mut cb Clipboard) get_text() string {
C.CloseClipboard()
return ''
}
str := unsafe { string_from_wide(&u16(C.GlobalLock(h_data))) }
C.GlobalUnlock(h_data)
str := unsafe { string_from_wide(&u16(C.GlobalLock(C.HGLOBAL(h_data)))) }
C.GlobalUnlock(C.HGLOBAL(h_data))
return str
}

View File

@ -25,45 +25,45 @@ struct C.Window {
fn C.XInitThreads() int
fn C.XCloseDisplay(d &Display)
fn C.XCloseDisplay(d &C.Display)
fn C.XFlush(d &Display)
fn C.XFlush(d &C.Display)
fn C.XDestroyWindow(d &Display, w C.Window)
fn C.XDestroyWindow(d &C.Display, w C.Window)
fn C.XNextEvent(d C.Display, e &XEvent)
fn C.XNextEvent(d &C.Display, e &C.XEvent)
fn C.XSetSelectionOwner(d &Display, a C.Atom, w C.Window, time int)
fn C.XSetSelectionOwner(d &C.Display, a C.Atom, w C.Window, time int)
fn C.XGetSelectionOwner(d &Display, a C.Atom) C.Window
fn C.XGetSelectionOwner(d &C.Display, a C.Atom) C.Window
fn C.XChangeProperty(d &Display, requestor C.Window, property C.Atom, typ C.Atom, format int, mode int, data voidptr, nelements int) int
fn C.XChangeProperty(d &C.Display, requestor C.Window, property C.Atom, typ C.Atom, format int, mode int, data voidptr, nelements int) int
fn C.XSendEvent(d &Display, requestor C.Window, propogate int, mask i64, event &XEvent)
fn C.XSendEvent(d &C.Display, requestor C.Window, propogate int, mask i64, event &C.XEvent)
fn C.XInternAtom(d &Display, typ byteptr, only_if_exists int) C.Atom
fn C.XInternAtom(d &C.Display, typ byteptr, only_if_exists int) C.Atom
fn C.XCreateSimpleWindow(d &Display, root C.Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) C.Window
fn C.XCreateSimpleWindow(d &C.Display, root C.Window, x int, y int, width u32, height u32, border_width u32, border u64, background u64) C.Window
fn C.XOpenDisplay(name byteptr) &C.Display
fn C.XConvertSelection(d &Display, selection C.Atom, target C.Atom, property C.Atom, requestor Window, time int) int
fn C.XConvertSelection(d &C.Display, selection C.Atom, target C.Atom, property C.Atom, requestor C.Window, time int) int
fn C.XSync(d &Display, discard int) int
fn C.XSync(d &C.Display, discard int) int
fn C.XGetWindowProperty(d &Display, w Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int
fn C.XGetWindowProperty(d &C.Display, w C.Window, property C.Atom, offset i64, length i64, delete int, req_type C.Atom, actual_type_return &C.Atom, actual_format_return &int, nitems &u64, bytes_after_return &u64, prop_return &byteptr) int
fn C.XDeleteProperty(d &Display, w Window, property C.Atom) int
fn C.XDeleteProperty(d &C.Display, w C.Window, property C.Atom) int
fn C.DefaultScreen() int
fn C.DefaultScreen(display &C.Display) int
fn C.RootWindow() voidptr
fn C.RootWindow(display &C.Display, screen_number int) C.Window
fn C.BlackPixel() voidptr
fn C.BlackPixel(display &C.Display, screen_number int) u32
fn C.WhitePixel() voidptr
fn C.WhitePixel(display &C.Display, screen_number int) u32
fn C.XFree()
fn C.XFree(data voidptr)
fn todo_del() {}
@ -404,7 +404,7 @@ fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
if ret != 0 {
C.XFree(ret)
}
C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, C.AnyPropertyType, &actual_type,
C.XGetWindowProperty(d, w, p, 0, read_bytes, 0, C.Atom(C.AnyPropertyType), &actual_type,
&actual_format, &nitems, &bytes_after, &ret)
read_bytes *= 2
if bytes_after == 0 {

View File

@ -8,12 +8,12 @@ module rand
#flag darwin -framework Security
fn C.SecRandomCopyBytes() int
fn C.SecRandomCopyBytes(rnd C.SecRandomRef, count size_t, bytes voidptr) int
// read returns an array of `bytes_needed` random bytes read from the OS.
pub fn read(bytes_needed int) ?[]byte {
mut buffer := []byte{ len: bytes_needed }
status := C.SecRandomCopyBytes(0, bytes_needed, buffer.data)
status := C.SecRandomCopyBytes(C.SecRandomRef(0), bytes_needed, buffer.data)
if status != 0 {
return read_error
}

View File

@ -5,9 +5,9 @@ pub const (
rtld_lazy = 0
)
fn C.LoadLibrary(libfilename C.LPCWSTR) voidptr
fn C.LoadLibrary(libfilename &u16) voidptr
fn C.GetProcAddress(handle voidptr, procname C.LPCSTR) voidptr
fn C.GetProcAddress(handle voidptr, procname byteptr) voidptr
fn C.FreeLibrary(handle voidptr) bool

View File

@ -34,7 +34,7 @@ struct C.MYSQL_FIELD {
fn C.mysql_init(mysql &C.MYSQL) &C.MYSQL
fn C.mysql_real_connect(mysql &C.MYSQL, host byteptr, user byteptr, passwd byteptr, db byteptr, port u32, unix_socket byteptr, clientflag u64) &C.MYSQL
fn C.mysql_real_connect(mysql &C.MYSQL, host charptr, user charptr, passwd charptr, db charptr, port u32, unix_socket charptr, client_flag ConnectionFlag) &C.MYSQL
fn C.mysql_query(mysql &C.MYSQL, q byteptr) int
@ -56,13 +56,13 @@ fn C.mysql_num_fields(res &C.MYSQL_RES) int
fn C.mysql_num_rows(res &C.MYSQL_RES) u64
fn C.mysql_autocommit(mysql MYSQL, mode bool)
fn C.mysql_autocommit(mysql &C.MYSQL, mode bool)
fn C.mysql_refresh(mysql MYSQL, options u32) int
fn C.mysql_refresh(mysql &C.MYSQL, options u32) int
fn C.mysql_reset_connection(mysql MYSQL) int
fn C.mysql_reset_connection(mysql &C.MYSQL) int
fn C.mysql_ping(mysql MYSQL) int
fn C.mysql_ping(mysql &C.MYSQL) int
fn C.mysql_store_result(mysql &C.MYSQL) &C.MYSQL_RES

View File

@ -11,10 +11,14 @@ enum Select {
pub enum SocketType {
udp = C.SOCK_DGRAM
tcp = C.SOCK_STREAM
dgram = C.SOCK_DGRAM
stream = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET
}
// SocketFamily are the available address families
pub enum SocketFamily {
unix = C.AF_UNIX
inet = C.AF_INET
}
@ -55,59 +59,71 @@ mut:
struct C.sockaddr_storage {
}
fn C.socket() int
fn C.socket(domain SocketFamily, typ SocketType, protocol int) int
fn C.setsockopt() int
// fn C.setsockopt(sockfd int, level int, optname int, optval voidptr, optlen C.socklen_t) int
fn C.setsockopt(sockfd int, level int, optname int, optval voidptr, optlen u32) int
fn C.htonl() int
fn C.htonl(hostlong u32) int
fn C.htons() int
fn C.htons(netshort u16) int
fn C.bind() int
// fn C.bind(sockfd int, addr &C.sockaddr, addrlen C.socklen_t) int
// use voidptr for arg 2 becasue sockaddr is a generic descriptor for any kind of socket operation,
// it can also take sockaddr_in depending on the type of socket used in arg 1
fn C.bind(sockfd int, addr voidptr, addrlen u32) int
fn C.listen() int
fn C.listen(sockfd int, backlog int) int
fn C.accept() int
// fn C.accept(sockfd int, addr &C.sockaddr, addrlen &C.socklen_t) int
fn C.accept(sockfd int, addr &C.sockaddr, addrlen &u32) int
fn C.getaddrinfo() int
fn C.getaddrinfo(node charptr, service charptr, hints &C.addrinfo, res &&C.addrinfo) int
fn C.connect() int
// fn C.connect(sockfd int, addr &C.sockaddr, addrlen C.socklen_t) int
fn C.connect(sockfd int, addr &C.sockaddr, addrlen u32) int
fn C.send() int
// fn C.send(sockfd int, buf voidptr, len size_t, flags int) size_t
fn C.send(sockfd int, buf voidptr, len size_t, flags int) int
fn C.sendto() int
// fn C.sendto(sockfd int, buf voidptr, len size_t, flags int, dest_add &C.sockaddr, addrlen C.socklen_t) size_t
fn C.sendto(sockfd int, buf voidptr, len size_t, flags int, dest_add &C.sockaddr, addrlen u32) int
fn C.recv() int
// fn C.recv(sockfd int, buf voidptr, len size_t, flags int) size_t
fn C.recv(sockfd int, buf voidptr, len size_t, flags int) int
fn C.recvfrom() int
// fn C.recvfrom(sockfd int, buf voidptr, len size_t, flags int, src_addr &C.sockaddr, addrlen &C.socklen_t) size_t
fn C.recvfrom(sockfd int, buf voidptr, len size_t, flags int, src_addr &C.sockaddr, addrlen &u32) int
fn C.shutdown() int
fn C.shutdown(socket int, how int) int
fn C.ntohs() int
fn C.ntohs(netshort u16) int
fn C.getpeername() int
// fn C.getpeername(sockfd int, addr &C.sockaddr, addlen &C.socklen_t) int
fn C.getpeername(sockfd int, addr &C.sockaddr, addlen &u32) int
fn C.inet_ntop(af int, src voidptr, dst charptr, dst_size int) charptr
fn C.inet_ntop(af SocketFamily, src voidptr, dst charptr, dst_size int) charptr
fn C.WSAAddressToStringA() int
fn C.WSAAddressToStringA(lpsaAddress &C.sockaddr, dwAddressLength u32, lpProtocolInfo voidptr, lpszAddressString charptr, lpdwAddressStringLength &u32) int
fn C.getsockname() int
// fn C.getsockname(sockfd int, addr &C.sockaddr, addrlen &C.socklen_t) int
fn C.getsockname(sockfd int, addr &C.sockaddr, addrlen &u32) int
// defined in builtin
// fn C.read() int
// fn C.close() int
fn C.ioctlsocket() int
fn C.ioctlsocket(s int, cmd int, argp &u32) int
fn C.fcntl() int
fn C.fcntl(fd int, cmd int, arg ...voidptr) int
fn C.@select() int
fn C.@select(ndfs int, readfds &C.fd_set, writefds &C.fd_set, exceptfds &C.fd_set, timeout &C.timeval) int
fn C.FD_ZERO()
fn C.FD_ZERO(fdset &C.fd_set)
fn C.FD_SET()
fn C.FD_SET(fd int, fdset &C.fd_set)
fn C.FD_ISSET() bool
fn C.FD_ISSET(fd int, fdset &C.fd_set) bool
[typedef]
pub struct C.fd_set {}

View File

@ -34,49 +34,52 @@ pub struct SSL {
pub struct SSL_METHOD {
}
fn C.BIO_new_ssl_connect() voidptr
fn C.BIO_new_ssl_connect(ctx &C.SSL_CTX) &C.BIO
fn C.BIO_set_conn_hostname() int
fn C.BIO_set_conn_hostname(b &C.BIO, name charptr) int
fn C.BIO_get_ssl()
// there are actually 2 macros for BIO_get_ssl
// fn C.BIO_get_ssl(bp &C.BIO, ssl charptr, c int)
// fn C.BIO_get_ssl(bp &C.BIO, sslp charptr)
fn C.BIO_get_ssl(bp &C.BIO, vargs ...voidptr)
fn C.BIO_do_connect() int
fn C.BIO_do_connect(b &C.BIO) int
fn C.BIO_do_handshake() int
fn C.BIO_do_handshake(b &C.BIO) int
fn C.BIO_puts()
fn C.BIO_puts(b &C.BIO, buf charptr)
fn C.BIO_read() int
fn C.BIO_read(b &C.BIO, buf voidptr, len int) int
fn C.BIO_free_all()
fn C.BIO_free_all(a &C.BIO)
fn C.SSL_CTX_new() &C.SSL_CTX
fn C.SSL_CTX_new(method &C.SSL_METHOD) &C.SSL_CTX
fn C.SSL_CTX_set_options()
fn C.SSL_CTX_set_options(ctx &C.SSL_CTX, options int)
fn C.SSL_CTX_set_verify_depth()
fn C.SSL_CTX_set_verify_depth(s &C.SSL_CTX, depth int)
fn C.SSL_CTX_load_verify_locations() int
fn C.SSL_CTX_load_verify_locations(ctx &C.SSL_CTX, ca_file charptr, ca_path charptr) int
fn C.SSL_CTX_free()
fn C.SSL_CTX_free(ctx &C.SSL_CTX)
fn C.SSL_new(&C.SSL_CTX) &C.SSL
fn C.SSL_set_fd(&C.SSL) int
fn C.SSL_set_fd(ssl &C.SSL, fd int) int
fn C.SSL_connect(&C.SSL) int
fn C.SSL_set_cipher_list() int
fn C.SSL_set_cipher_list(ctx &SSL, str charptr) int
fn C.SSL_get_peer_certificate() int
fn C.SSL_get_peer_certificate(ssl &SSL) &C.X509
fn C.ERR_clear_error()
fn C.SSL_get_error() int
fn C.SSL_get_error(ssl &C.SSL, ret int) int
fn C.SSL_get_verify_result() int
fn C.SSL_get_verify_result(ssl &SSL) int
fn C.SSL_set_tlsext_host_name() int
fn C.SSL_set_tlsext_host_name(s &SSL, name charptr) int
fn C.SSL_shutdown(&C.SSL) int

View File

@ -157,7 +157,7 @@ pub fn (c &TcpConn) peer_ip() ?string {
peeraddr := C.sockaddr_in{}
speeraddr := sizeof(peeraddr)
socket_error(C.getpeername(c.sock.handle, unsafe { &C.sockaddr(&peeraddr) }, &speeraddr)) ?
cstr := charptr(C.inet_ntop(C.AF_INET, &peeraddr.sin_addr, buf, sizeof(buf)))
cstr := charptr(C.inet_ntop(SocketFamily.inet, &peeraddr.sin_addr, buf, sizeof(buf)))
if cstr == 0 {
return error('net.peer_ip: inet_ntop failed')
}
@ -264,7 +264,7 @@ fn new_tcp_socket() ?TcpSocket {
// s.set_option_bool(.reuse_addr, true)?
s.set_option_int(.reuse_addr, 1) ?
$if windows {
t := true
t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else {
socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ?
@ -279,7 +279,7 @@ fn tcp_socket_from_handle(sockfd int) ?TcpSocket {
// s.set_option_bool(.reuse_addr, true)?
s.set_option_int(.reuse_addr, 1) ?
$if windows {
t := true
t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else {
socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ?

View File

@ -181,7 +181,7 @@ fn new_udp_socket(local_port int) ?&UdpSocket {
}
s.set_option_bool(.reuse_addr, true) ?
$if windows {
t := true
t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else {
socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK)) ?

View File

@ -8,11 +8,11 @@ enum Select {
}
// SocketType are the available sockets
enum SocketType {
dgram = C.SOCK_DGRAM
stream = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET
}
// enum SocketType {
// dgram = C.SOCK_DGRAM
// stream = C.SOCK_STREAM
// seqpacket = C.SOCK_SEQPACKET
// }
struct C.sockaddr {
sa_family u16
@ -44,43 +44,43 @@ mut:
struct C.sockaddr_storage {
}
fn C.socket() int
// fn C.socket() int
fn C.setsockopt() int
// fn C.setsockopt() int
fn C.htonl() int
// fn C.htonl() int
fn C.htons() int
// fn C.htons() int
fn C.bind() int
// fn C.bind() int
fn C.listen() int
// fn C.listen() int
fn C.accept() int
// fn C.accept() int
fn C.getaddrinfo() int
// fn C.getaddrinfo() int
fn C.connect() int
// fn C.connect() int
fn C.send() int
// fn C.send() int
fn C.sendto() int
// fn C.sendto() int
fn C.recv() int
// fn C.recv() int
fn C.recvfrom() int
// fn C.recvfrom() int
fn C.shutdown() int
// fn C.shutdown() int
fn C.ntohs() int
// fn C.ntohs() int
fn C.getpeername() int
// fn C.getpeername() int
fn C.inet_ntop(af int, src voidptr, dst charptr, dst_size int) charptr
// fn C.inet_ntop(af int, src voidptr, dst charptr, dst_size int) charptr
fn C.WSAAddressToStringA() int
fn C.getsockname() int
// fn C.getsockname() int
// defined in builtin
// fn C.read() int
@ -88,15 +88,15 @@ fn C.getsockname() int
fn C.ioctlsocket() int
fn C.fcntl() int
// fn C.fcntl() int
fn C.@select() int
// fn C.@select() int
fn C.FD_ZERO()
// fn C.FD_ZERO()
fn C.FD_SET()
// fn C.FD_SET()
fn C.FD_ISSET() bool
// fn C.FD_ISSET() bool
[typedef]
struct C.fd_set {}

View File

@ -7,7 +7,7 @@ const (
error_ewouldblock = C.EWOULDBLOCK
)
fn C.SUN_LEN(C.sockaddr_un) int
fn C.SUN_LEN(ptr &C.sockaddr_un) int
fn C.strncpy(charptr, charptr, int)

View File

@ -41,7 +41,7 @@ fn error_code() int {
}
fn new_stream_socket() ?StreamSocket {
sockfd := net.socket_error(C.socket(C.AF_UNIX, SocketType.stream, 0)) ?
sockfd := net.socket_error(C.socket(net.SocketFamily.unix, net.SocketType.stream, 0)) ?
mut s := StreamSocket{
handle: sockfd
}

View File

@ -9,7 +9,7 @@ struct C.dirent {
fn C.readdir(voidptr) &C.dirent
fn C.readlink() int
fn C.readlink(pathname charptr, buf charptr, bufsiz size_t) int
fn C.getline(voidptr, voidptr, voidptr) int
@ -19,7 +19,7 @@ fn C.sigaction(int, voidptr, int)
fn C.open(charptr, int, ...int) int
fn C.fdopen(int, string) voidptr
fn C.fdopen(fd int, mode charptr) &C.FILE
fn C.CopyFile(&u32, &u32, int) int
@ -408,8 +408,7 @@ pub fn get_raw_line() string {
h_input := C.GetStdHandle(C.STD_INPUT_HANDLE)
mut bytes_read := 0
if is_atty(0) > 0 {
x := C.ReadConsole(h_input, buf, max_line_chars * 2, C.LPDWORD(&bytes_read),
0)
x := C.ReadConsole(h_input, buf, max_line_chars * 2, &bytes_read, 0)
if !x {
return tos(buf, 0)
}

View File

@ -40,39 +40,48 @@ struct C.sockaddr_storage {
fn C.atoi() int
fn C.strncasecmp() int
fn C.strncasecmp(s1 charptr, s2 charptr, n size_t) int
fn C.socket() int
fn C.socket(domain int, typ int, protocol int) int
fn C.setsockopt() int
// fn C.setsockopt(sockfd int, level int, optname int, optval voidptr, optlen C.socklen_t) int
fn C.setsockopt(sockfd int, level int, optname int, optval voidptr, optlen u32) int
fn C.htonl() int
fn C.htonl(hostlong u32) int
fn C.htons() int
fn C.htons(netshort u16) int
fn C.bind() int
// fn C.bind(sockfd int, addr &C.sockaddr, addrlen C.socklen_t) int
// use voidptr for arg 2 becasue sockaddr is a generic descriptor for any kind of socket operation,
// it can also take sockaddr_in depending on the type of socket used in arg 1
fn C.bind(sockfd int, addr voidptr, addrlen u32) int
fn C.listen() int
fn C.listen(sockfd int, backlog int) int
fn C.accept() int
// fn C.accept(sockfd int, addr &C.sockaddr, addrlen &C.socklen_t) int
fn C.accept(sockfd int, addr &C.sockaddr, addrlen &u32) int
fn C.getaddrinfo() int
fn C.getaddrinfo(node charptr, service charptr, hints &C.addrinfo, res &&C.addrinfo) int
fn C.connect() int
// fn C.connect(sockfd int, addr &C.sockaddr, addrlen C.socklen_t) int
fn C.connect(sockfd int, addr &C.sockaddr, addrlen u32) int
fn C.send() int
// fn C.send(sockfd int, buf voidptr, len size_t, flags int) size_t
fn C.send(sockfd int, buf voidptr, len size_t, flags int) int
fn C.recv() int
// fn C.recv(sockfd int, buf voidptr, len size_t, flags int) size_t
fn C.recv(sockfd int, buf voidptr, len size_t, flags int) int
// fn C.read() int
fn C.shutdown() int
fn C.shutdown(socket int, how int) int
// fn C.close() int
fn C.ntohs() int
fn C.ntohs(netshort u16) int
fn C.getsockname() int
// fn C.getsockname(sockfd int, addr &C.sockaddr, addrlen &C.socklen_t) int
fn C.getsockname(sockfd int, addr &C.sockaddr, addrlen &u32) int
fn C.fcntl() int
fn C.fcntl(fd int, cmd int, arg ...voidptr) int
// fn C.write() int
struct C.picoev_loop {
@ -93,7 +102,11 @@ fn C.picoev_del(&C.picoev_loop, int) int
fn C.picoev_set_timeout(&C.picoev_loop, int, int)
fn C.picoev_add(&C.picoev_loop, int, int, int, &C.picoev_handler, voidptr) int
// fn C.picoev_handler(loop &C.picoev_loop, fd int, revents int, cb_arg voidptr)
// TODO: (sponge) update to C.picoev_handler with C type def update
type Cpicoev_handler = fn(loop &C.picoev_loop, fd int, revents int, cb_arg voidptr)
fn C.picoev_add(&C.picoev_loop, int, int, int, &Cpicoev_handler, voidptr) int
fn C.picoev_init(int) int
@ -105,12 +118,6 @@ fn C.picoev_destroy_loop(&C.picoev_loop) int
fn C.picoev_deinit() int
fn C.phr_parse_request() int
fn C.phr_parse_request_path_pipeline() int
fn C.phr_parse_request_path() int
[inline]
fn setup_sock(fd int) {
on := 1

View File

@ -16,13 +16,17 @@ pub:
value charptr
value_len int
}
struct C.phr_header_t {}
fn C.phr_parse_request() int
fn C.phr_parse_response() int
fn C.phr_parse_headers() int
fn C.phr_parse_request(buf charptr, len size_t, method &charptr, method_len &size_t, path &charptr, path_len &size_t, minor_version &int, headers &C.phr_header, num_headers &size_t, last_len size_t) int
fn C.phr_parse_request_path() int
fn C.phr_parse_request_path_pipeline() int
fn C.phr_parse_response(buf charptr, len size_t, minor_version &int, status &int, msg &charptr, msg_len &size_t, headers &C.phr_header, num_headers &size_t, last_len size_t) int
fn C.phr_parse_headers(buf charptr, len size_t, headers &C.phr_header, num_headers &size_t, last_len size_t) int
fn C.phr_parse_request_path(buf_start charptr, len size_t, method &charptr, method_len &size_t, path &charptr, path_len &size_t) int
fn C.phr_parse_request_path_pipeline(buf_start charptr, len size_t, method &charptr, method_len &size_t, path &charptr, path_len &size_t) int
fn C.get_date() byteptr
fn C.u64toa() int
// char * u64toa(uint64_t value, char *buffer)
fn C.u64toa(value u64, buffer charptr) charptr

View File

@ -21,8 +21,8 @@ pub fn (mut r Request) parse_request(s string, max_headers int) int {
pret := C.phr_parse_request(
s.str, s.len,
&r.method, &method_len,
&r.path, &path_len,
&r.method.str, &method_len,
&r.path.str, &path_len,
&minor_version,
r.headers, &num_headers,
0
@ -44,8 +44,8 @@ pub fn (mut r Request) parse_request_path(s string) int {
pret := C.phr_parse_request_path(
s.str, s.len,
&r.method, &method_len,
&r.path, &path_len
&r.method.str, &method_len,
&r.path.str, &path_len
)
if pret > 0 {
unsafe {
@ -63,8 +63,8 @@ pub fn (mut r Request) parse_request_path_pipeline(s string) int {
pret := C.phr_parse_request_path_pipeline(
s.str, s.len,
&r.method, &method_len,
&r.path, &path_len
&r.method.str, &method_len,
&r.path.str, &path_len
)
if pret > 0 {
unsafe {

View File

@ -12,11 +12,11 @@ import os
#include <termios.h>
#include <sys/ioctl.h>
fn C.tcgetattr() int
fn C.tcgetattr(fd int, termios_p &Termios) int
fn C.tcsetattr() int
fn C.tcsetattr(fd int, optional_actions int, termios_p &Termios) int
fn C.raise()
fn C.raise(sig int)
fn C.getppid() int

View File

@ -1,6 +1,6 @@
module sfons
fn C.sfons_create(width int, height int, flags int) &C.FONScontext
fn C.sfons_destroy(ctx &FONScontext)
fn C.sfons_destroy(ctx &C.FONScontext)
fn C.sfons_rgba(r byte, g byte, b byte, a byte) u32
fn C.sfons_flush(ctx &FONScontext)
fn C.sfons_flush(ctx &C.FONScontext)

View File

@ -41,7 +41,7 @@ fn C.sqlite3_open(charptr, &&C.sqlite3) int
fn C.sqlite3_close(&C.sqlite3) int
//
fn C.sqlite3_prepare_v2(&C.sqlite3, charptr, int, &&sqlite3_stmt, &charptr) int
fn C.sqlite3_prepare_v2(&C.sqlite3, charptr, int, &&C.sqlite3_stmt, &charptr) int
fn C.sqlite3_step(&C.sqlite3_stmt) int

View File

@ -4,6 +4,7 @@ import os
#include <sys/ioctl.h>
#include <termios.h> // TIOCGWINSZ
pub struct C.winsize {
pub:
ws_row u16
@ -20,7 +21,7 @@ pub fn get_terminal_size() (int, int) {
return default_columns_size, default_rows_size
}
w := C.winsize{}
C.ioctl(1, C.TIOCGWINSZ, &w)
C.ioctl(1, u64(C.TIOCGWINSZ), &w)
return int(w.ws_col), int(w.ws_row)
}

View File

@ -44,16 +44,16 @@ mut:
}
// ref - https://docs.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
fn C.GetConsoleScreenBufferInfo(handle os.HANDLE, info &C.CONSOLE_SCREEN_BUFFER_INFO) bool
fn C.GetConsoleScreenBufferInfo(handle C.HANDLE, info &C.CONSOLE_SCREEN_BUFFER_INFO) bool
// ref - https://docs.microsoft.com/en-us/windows/console/setconsoletitle
fn C.SetConsoleTitle(title &u16) bool
// ref - https://docs.microsoft.com/en-us/windows/console/setconsolecursorposition
fn C.SetConsoleCursorPosition(handle os.HANDLE, coord C.COORD) bool
fn C.SetConsoleCursorPosition(handle C.HANDLE, coord C.COORD) bool
// ref - https://docs.microsoft.com/en-us/windows/console/scrollconsolescreenbuffer
fn C.ScrollConsoleScreenBuffer(output os.HANDLE, scroll_rect &C.SMALL_RECT, clip_rect &C.SMALL_RECT, des C.COORD, fill C.CHAR_INFO) bool
fn C.ScrollConsoleScreenBuffer(output C.HANDLE, scroll_rect &C.SMALL_RECT, clip_rect &C.SMALL_RECT, des C.COORD, fill &C.CHAR_INFO) bool
// get_terminal_size returns a number of colums and rows of terminal window.
pub fn get_terminal_size() (int, int) {

View File

@ -77,8 +77,8 @@ struct C.CONSOLE_SCREEN_BUFFER_INFO {
dwMaximumWindowSize C.COORD
}
fn C.ReadConsoleInput() bool
fn C.ReadConsoleInput(hConsoleInput C.HANDLE, lpBuffer &C.INPUT_RECORD, nLength u32, lpNumberOfEventsRead &u32) bool
fn C.GetNumberOfConsoleInputEvents() bool
fn C.GetNumberOfConsoleInputEvents(hConsoleInput C.HANDLE, lpcNumberOfEvents &u32) bool
fn C.GetConsoleScreenBufferInfo(handle os.HANDLE, info &C.CONSOLE_SCREEN_BUFFER_INFO) bool
fn C.GetConsoleScreenBufferInfo(handle C.HANDLE, info &C.CONSOLE_SCREEN_BUFFER_INFO) bool

View File

@ -10,9 +10,9 @@ import time
#include <sys/ioctl.h>
#include <signal.h>
fn C.tcgetattr()
fn C.tcgetattr(fd int, termios_p &C.termios) int
fn C.tcsetattr()
fn C.tcsetattr(fd int, optional_actions int, termios_p &C.termios) int
fn C.ioctl(fd int, request u64, arg voidptr) int

View File

@ -17,10 +17,10 @@ struct C.tm {
tm_isdst int
}
fn C.timegm(&tm) time_t
fn C.timegm(&C.tm) time_t
// fn C.gmtime_r(&tm, &gbuf)
fn C.localtime_r(t &C.time_t, tm &C.tm)
fn C.localtime_r(t &time_t, tm &C.tm)
fn make_unix_time(t C.tm) int {
return int(C.timegm(&t))

View File

@ -29,11 +29,11 @@ struct SystemTime {
millisecond u16
}
fn C.GetSystemTimeAsFileTime(lpSystemTimeAsFileTime C._FILETIME)
fn C.GetSystemTimeAsFileTime(lpSystemTimeAsFileTime &C._FILETIME)
fn C.FileTimeToSystemTime()
fn C.FileTimeToSystemTime(lpFileTime &C._FILETIME, lpSystemTime &SystemTime)
fn C.SystemTimeToTzSpecificLocalTime()
fn C.SystemTimeToTzSpecificLocalTime(lpTimeZoneInformation &C.TIME_ZONE_INFORMATION, lpUniversalTime &SystemTime, lpLocalTime &SystemTime)
fn C.localtime_s(t &C.time_t, tm &C.tm)

View File

@ -7,7 +7,7 @@ import v.table
import v.token
import v.ast
pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.Type) ? {
pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.Type, language table.Language) ? {
mut expected := expected_
// variadic
if expected.has_flag(.variadic) {
@ -15,6 +15,39 @@ pub fn (mut c Checker) check_expected_call_arg(got table.Type, expected_ table.T
exp_info := exp_type_sym.info as table.Array
expected = exp_info.elem_type
}
if language == .c {
// allow number types to be used interchangeably
if got.is_number() && expected.is_number() {
return
}
// mode_t - currently using u32 as mode_t for C fns
// if got.idx() in [table.int_type_idx, table.u32_type_idx] && expected.idx() in [table.int_type_idx, table.u32_type_idx] {
// return
// }
// allow number to be used as size_t
if got.is_number() && expected.idx() == table.size_t_type_idx {
return
}
// allow bool & int to be used interchangeably for C functions
if (got.idx() == table.bool_type_idx
&& expected.idx() in [table.int_type_idx, table.int_literal_type_idx])
|| (expected.idx() == table.bool_type_idx
&& got.idx() in [table.int_type_idx, table.int_literal_type_idx]) {
return
}
if got.idx() == table.string_type_idx
&& expected in [table.byteptr_type_idx, table.charptr_type_idx] {
return
}
exp_sym := c.table.get_type_symbol(expected)
// unknown C types are set to int, allow int to be used for types like `&C.FILE`
// eg. `C.fflush(C.stderr)` - error: cannot use `int` as `&C.FILE` in argument 1 to `C.fflush`
if expected.is_ptr() && exp_sym.language == .c && exp_sym.kind == .placeholder
&& got == table.int_type_idx {
return
}
// return
}
if c.check_types(got, expected) {
return
}
@ -46,6 +79,17 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
return true
}
}
// e.g. [4096]byte vs byteptr || [4096]char vs charptr
// should charptr be allowed as byteptr etc?
// TODO: clean this up (why was it removed?)
if got_sym.kind == .array_fixed {
info := got_sym.info as table.ArrayFixed
if !info.elem_type.is_ptr() && (info.elem_type.idx() == expected.idx()
|| (info.elem_type.idx() in [table.byte_type_idx, table.char_type_idx]
&& expected.idx() in [table.byteptr_type_idx, table.charptr_type_idx])) {
return true
}
}
if exp_sym.kind in [.voidptr, .any] || got_sym.kind in [.voidptr, .any] {
return true
}
@ -157,7 +201,7 @@ fn (c &Checker) promote_num(left_type table.Type, right_type table.Type) table.T
}
idx_hi := type_hi.idx()
idx_lo := type_lo.idx()
// the following comparisons rely on the order of the indices in atypes.v
// the following comparisons rely on the order of the indices in table/types.v
if idx_hi == table.int_literal_type_idx {
return type_lo
} else if idx_hi == table.float_literal_type_idx {

View File

@ -1546,7 +1546,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
if method.generic_names.len > 0 {
continue
}
c.check_expected_call_arg(got_arg_typ, exp_arg_typ) or {
c.check_expected_call_arg(got_arg_typ, exp_arg_typ, call_expr.language) or {
// str method, allow type with str method if fn arg is string
// Passing an int or a string array produces a c error here
// Deleting this condition results in propper V error messages
@ -1866,22 +1866,8 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
&& f.ctdefine !in c.pref.compile_defines {
call_expr.should_be_skipped = true
}
if f.language != .v || call_expr.language != .v {
// ignore C function of type `fn()`, assume untyped
// For now don't check C functions that are variadic, underscored, capitalized
// or have no params or attributes and return int
if f.language == .c && f.params.len != call_expr.args.len && !f.is_variadic
&& f.name[2] != `_` && !f.name[2].is_capital() && (f.params.len != 0
|| f.return_type !in [table.void_type, table.int_type]
|| f.attrs.len > 0) {
// change to error later
c.warn('expected $f.params.len arguments, but got $call_expr.args.len', call_expr.pos)
}
for arg in call_expr.args {
c.expr(arg.expr)
}
return f.return_type
}
// dont check number of args for JS functions since arguments are not required
if call_expr.language != .js {
min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len }
if call_expr.args.len < min_required_args {
c.error('expected $min_required_args arguments, but got $call_expr.args.len',
@ -1893,6 +1879,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
unexpected_arguments_pos)
return f.return_type
}
}
// println / eprintln / panic can print anything
if fn_name in ['println', 'print', 'eprintln', 'eprint', 'panic'] && call_expr.args.len > 0 {
c.inside_println_arg = true
@ -1960,7 +1947,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block',
call_arg.pos)
}
if call_arg.is_mut {
if call_arg.is_mut && f.language == .v {
to_lock, pos := c.fail_if_immutable(call_arg.expr)
if !arg.is_mut {
tok := call_arg.share.str()
@ -1991,7 +1978,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
c.type_implements(typ, arg.typ, call_arg.expr.position())
continue
}
c.check_expected_call_arg(typ, arg.typ) or {
c.check_expected_call_arg(typ, arg.typ, call_expr.language) or {
// str method, allow type with str method if fn arg is string
// Passing an int or a string array produces a c error here
// Deleting this condition results in propper V error messages

View File

@ -1,3 +1,10 @@
vlib/v/checker/tests/c_fn_surplus_args.vv:6:7: error: expected 0 arguments, but got 1
4 |
5 | fn main() {
6 | C.no(1) // allowed
| ^
7 | C.y1()
8 | C.y1(1) // ok
vlib/v/checker/tests/c_fn_surplus_args.vv:7:4: error: expected 1 arguments, but got 0
5 | fn main() {
6 | C.no(1) // allowed
@ -5,18 +12,18 @@ vlib/v/checker/tests/c_fn_surplus_args.vv:7:4: error: expected 1 arguments, but
| ~~~~
8 | C.y1(1) // ok
9 | C.y1(1, 2)
vlib/v/checker/tests/c_fn_surplus_args.vv:9:4: error: expected 1 arguments, but got 2
vlib/v/checker/tests/c_fn_surplus_args.vv:9:10: error: expected 1 arguments, but got 2
7 | C.y1()
8 | C.y1(1) // ok
9 | C.y1(1, 2)
| ~~~~~~~~
| ^
10 | C.ret() // ok
11 | C.ret(1)
vlib/v/checker/tests/c_fn_surplus_args.vv:11:4: error: expected 0 arguments, but got 1
vlib/v/checker/tests/c_fn_surplus_args.vv:11:8: error: expected 0 arguments, but got 1
9 | C.y1(1, 2)
10 | C.ret() // ok
11 | C.ret(1)
| ~~~~~~
| ^
12 | // avoid cgen whilst warning, later above should error
13 | main()
vlib/v/checker/tests/c_fn_surplus_args.vv:13:2: error: the `main` function cannot be called in the program
@ -26,10 +33,10 @@ vlib/v/checker/tests/c_fn_surplus_args.vv:13:2: error: the `main` function canno
| ~~~~~~
14 | C.af() // ok
15 | C.af(3)
vlib/v/checker/tests/c_fn_surplus_args.vv:15:4: error: expected 0 arguments, but got 1
vlib/v/checker/tests/c_fn_surplus_args.vv:15:7: error: expected 0 arguments, but got 1
13 | main()
14 | C.af() // ok
15 | C.af(3)
| ~~~~~
| ^
16 | }
17 |

View File

@ -1000,8 +1000,9 @@ fn (mut g Gen) autofree_call_postgen(node_pos int) {
fn (mut g Gen) call_args(node ast.CallExpr) {
args := if g.is_js_call { node.args[1..] } else { node.args }
expected_types := node.expected_arg_types
// only v variadic, C variadic args will be appeneded like normal args
is_variadic := expected_types.len > 0
&& expected_types[expected_types.len - 1].has_flag(.variadic)
&& expected_types[expected_types.len - 1].has_flag(.variadic) && node.language == .v
for i, arg in args {
if is_variadic && i == expected_types.len - 1 {
break
@ -1024,7 +1025,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
g.write('/*af arg*/' + name)
}
} else {
g.ref_or_deref_arg(arg, expected_types[i])
g.ref_or_deref_arg(arg, expected_types[i], node.language)
}
} else {
if use_tmp_var_autofree {
@ -1054,7 +1055,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
if variadic_count > 0 {
g.write('new_array_from_c_array($variadic_count, $variadic_count, sizeof($elem_type), _MOV(($elem_type[$variadic_count]){')
for j in arg_nr .. args.len {
g.ref_or_deref_arg(args[j], arr_info.elem_type)
g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language)
if j < args.len - 1 {
g.write(', ')
}
@ -1068,7 +1069,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
}
[inline]
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type, lang table.Language) {
arg_is_ptr := expected_type.is_ptr() || expected_type.idx() in table.pointer_type_idxs
expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs
if expected_type == 0 {
@ -1104,7 +1105,8 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
expected_type
}
deref_sym := g.table.get_type_symbol(expected_deref_type)
if !((arg_typ_sym.kind == .function) || deref_sym.kind in [.sum_type, .interface_]) {
if !((arg_typ_sym.kind == .function)
|| deref_sym.kind in [.sum_type, .interface_]) && lang != .c {
g.write('(voidptr)&/*qq*/')
}
}

View File

@ -672,7 +672,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
}
}
fn C.strtol() int
fn C.strtol(str charptr, endptr &&char, base int) int
fn (mut g Gen) expr(node ast.Expr) {
// println('cgen expr()')

View File

@ -302,7 +302,7 @@ pub const (
array_type_idx = 21
map_type_idx = 22
chan_type_idx = 23
sizet_type_idx = 24
size_t_type_idx = 24
any_type_idx = 25
float_literal_type_idx = 26
int_literal_type_idx = 27