From 2d73411396295ed1c65384019666477bf94ecc1d Mon Sep 17 00:00:00 2001 From: joe-conigliaro Date: Sat, 6 Mar 2021 01:41:11 +1100 Subject: [PATCH] checker: define missing C fn args & check C & JS args (#8770) --- doc/docs.md | 8 +- examples/wkhtmltopdf.v | 2 +- vlib/builtin/cfns.c.v | 126 +++++++++++---------- vlib/clipboard/clipboard_windows.c.v | 10 +- vlib/clipboard/x11/clipboard.c.v | 40 +++---- vlib/crypto/rand/rand_darwin.c.v | 4 +- vlib/dl/dl_windows.c.v | 4 +- vlib/mysql/_cdefs.c.v | 10 +- vlib/net/aasocket.c.v | 66 +++++++---- vlib/net/openssl/c.v | 41 +++---- vlib/net/tcp.v | 6 +- vlib/net/udp.v | 2 +- vlib/net/unix/aasocket.c.v | 56 ++++----- vlib/net/unix/common.v | 2 +- vlib/net/unix/stream_nix.v | 2 +- vlib/os/os_c.v | 7 +- vlib/picoev/picoev.v | 53 +++++---- vlib/picohttpparser/picohttpparser.v | 22 ++-- vlib/picohttpparser/request.v | 12 +- vlib/readline/readline_linux.c.v | 6 +- vlib/sokol/sfons/sfons_funcs.v | 4 +- vlib/sqlite/sqlite.v | 2 +- vlib/term/term_nix.c.v | 5 +- vlib/term/term_windows.c.v | 6 +- vlib/term/ui/consoleapi_windows.c.v | 6 +- vlib/term/ui/termios_nix.c.v | 4 +- vlib/time/time_nix.c.v | 4 +- vlib/time/time_windows.c.v | 6 +- vlib/v/checker/check_types.v | 48 +++++++- vlib/v/checker/checker.v | 43 +++---- vlib/v/checker/tests/c_fn_surplus_args.out | 19 +++- vlib/v/gen/c/fn.v | 12 +- vlib/v/gen/x64/gen.v | 2 +- vlib/v/table/types.v | 2 +- 34 files changed, 358 insertions(+), 284 deletions(-) diff --git a/doc/docs.md b/doc/docs.md index ff23859ff7..3b9d4b8d8f 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -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) diff --git a/examples/wkhtmltopdf.v b/examples/wkhtmltopdf.v index c519ed5211..a5b6b944df 100644 --- a/examples/wkhtmltopdf.v +++ b/examples/wkhtmltopdf.v @@ -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') diff --git a/vlib/builtin/cfns.c.v b/vlib/builtin/cfns.c.v index 5cb47e6e39..02e3380e5a 100644 --- a/vlib/builtin/cfns.c.v +++ b/vlib/builtin/cfns.c.v @@ -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 diff --git a/vlib/clipboard/clipboard_windows.c.v b/vlib/clipboard/clipboard_windows.c.v index b1f696d7bd..f78566e0ca 100644 --- a/vlib/clipboard/clipboard_windows.c.v +++ b/vlib/clipboard/clipboard_windows.c.v @@ -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 } diff --git a/vlib/clipboard/x11/clipboard.c.v b/vlib/clipboard/x11/clipboard.c.v index bd00fbef26..ac632d7f7d 100644 --- a/vlib/clipboard/x11/clipboard.c.v +++ b/vlib/clipboard/x11/clipboard.c.v @@ -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 { diff --git a/vlib/crypto/rand/rand_darwin.c.v b/vlib/crypto/rand/rand_darwin.c.v index e42e762869..c642ee4b28 100644 --- a/vlib/crypto/rand/rand_darwin.c.v +++ b/vlib/crypto/rand/rand_darwin.c.v @@ -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 } diff --git a/vlib/dl/dl_windows.c.v b/vlib/dl/dl_windows.c.v index 631ece2b4a..e057f186ae 100644 --- a/vlib/dl/dl_windows.c.v +++ b/vlib/dl/dl_windows.c.v @@ -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 diff --git a/vlib/mysql/_cdefs.c.v b/vlib/mysql/_cdefs.c.v index c3baa13458..5fe43733d3 100644 --- a/vlib/mysql/_cdefs.c.v +++ b/vlib/mysql/_cdefs.c.v @@ -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 diff --git a/vlib/net/aasocket.c.v b/vlib/net/aasocket.c.v index 15344a87d9..8b75e7f169 100644 --- a/vlib/net/aasocket.c.v +++ b/vlib/net/aasocket.c.v @@ -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 {} diff --git a/vlib/net/openssl/c.v b/vlib/net/openssl/c.v index 065f4520dc..e956931a45 100644 --- a/vlib/net/openssl/c.v +++ b/vlib/net/openssl/c.v @@ -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 diff --git a/vlib/net/tcp.v b/vlib/net/tcp.v index 3bb62e988e..902443af0e 100644 --- a/vlib/net/tcp.v +++ b/vlib/net/tcp.v @@ -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)) ? diff --git a/vlib/net/udp.v b/vlib/net/udp.v index fac1320d59..8f674445f7 100644 --- a/vlib/net/udp.v +++ b/vlib/net/udp.v @@ -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)) ? diff --git a/vlib/net/unix/aasocket.c.v b/vlib/net/unix/aasocket.c.v index a40639e54a..25abb47066 100644 --- a/vlib/net/unix/aasocket.c.v +++ b/vlib/net/unix/aasocket.c.v @@ -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 {} diff --git a/vlib/net/unix/common.v b/vlib/net/unix/common.v index c2779a5cb8..c44d9973d1 100644 --- a/vlib/net/unix/common.v +++ b/vlib/net/unix/common.v @@ -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) diff --git a/vlib/net/unix/stream_nix.v b/vlib/net/unix/stream_nix.v index 120d689851..0a23ed8bca 100644 --- a/vlib/net/unix/stream_nix.v +++ b/vlib/net/unix/stream_nix.v @@ -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 } diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index 8ed3e98dac..250cffdf7b 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -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) } diff --git a/vlib/picoev/picoev.v b/vlib/picoev/picoev.v index 6b7825dbd2..58678d69fc 100644 --- a/vlib/picoev/picoev.v +++ b/vlib/picoev/picoev.v @@ -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 diff --git a/vlib/picohttpparser/picohttpparser.v b/vlib/picohttpparser/picohttpparser.v index 98182aff1c..1dc9b31fcf 100644 --- a/vlib/picohttpparser/picohttpparser.v +++ b/vlib/picohttpparser/picohttpparser.v @@ -11,18 +11,22 @@ module picohttpparser struct C.phr_header { pub: - name charptr - name_len int - value charptr + name charptr + name_len int + 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 diff --git a/vlib/picohttpparser/request.v b/vlib/picohttpparser/request.v index 573cfd3076..60ba3125c1 100644 --- a/vlib/picohttpparser/request.v +++ b/vlib/picohttpparser/request.v @@ -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 { diff --git a/vlib/readline/readline_linux.c.v b/vlib/readline/readline_linux.c.v index ad195e5f9f..3dd521181d 100644 --- a/vlib/readline/readline_linux.c.v +++ b/vlib/readline/readline_linux.c.v @@ -12,11 +12,11 @@ import os #include #include -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 diff --git a/vlib/sokol/sfons/sfons_funcs.v b/vlib/sokol/sfons/sfons_funcs.v index ea49749a22..cec30d688f 100644 --- a/vlib/sokol/sfons/sfons_funcs.v +++ b/vlib/sokol/sfons/sfons_funcs.v @@ -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) diff --git a/vlib/sqlite/sqlite.v b/vlib/sqlite/sqlite.v index 4902e852e7..ccc9638b54 100644 --- a/vlib/sqlite/sqlite.v +++ b/vlib/sqlite/sqlite.v @@ -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 diff --git a/vlib/term/term_nix.c.v b/vlib/term/term_nix.c.v index 837cdede33..6dab16ae4c 100644 --- a/vlib/term/term_nix.c.v +++ b/vlib/term/term_nix.c.v @@ -4,6 +4,7 @@ import os #include #include // 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) } @@ -52,7 +53,7 @@ pub fn get_cursor_position() Coord { i++ if i >= 15 { panic('C.getchar() called too many times') - } + } // state management: if b == `R` { break diff --git a/vlib/term/term_windows.c.v b/vlib/term/term_windows.c.v index bd579f72d0..74d259de08 100644 --- a/vlib/term/term_windows.c.v +++ b/vlib/term/term_windows.c.v @@ -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) { diff --git a/vlib/term/ui/consoleapi_windows.c.v b/vlib/term/ui/consoleapi_windows.c.v index 19d521a0d0..96b3cc4017 100644 --- a/vlib/term/ui/consoleapi_windows.c.v +++ b/vlib/term/ui/consoleapi_windows.c.v @@ -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 diff --git a/vlib/term/ui/termios_nix.c.v b/vlib/term/ui/termios_nix.c.v index 4672125977..6a338281ca 100644 --- a/vlib/term/ui/termios_nix.c.v +++ b/vlib/term/ui/termios_nix.c.v @@ -10,9 +10,9 @@ import time #include #include -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 diff --git a/vlib/time/time_nix.c.v b/vlib/time/time_nix.c.v index 47a17f60dc..79f06c884c 100644 --- a/vlib/time/time_nix.c.v +++ b/vlib/time/time_nix.c.v @@ -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)) diff --git a/vlib/time/time_windows.c.v b/vlib/time/time_windows.c.v index 1aa9bef937..974416b161 100644 --- a/vlib/time/time_windows.c.v +++ b/vlib/time/time_windows.c.v @@ -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) diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 7ad0b96345..13e2857bd5 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -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 { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 5656c94e1d..3d574124f8 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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,32 +1866,19 @@ 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) + // 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', + call_expr.pos) + } else if !f.is_variadic && call_expr.args.len > f.params.len { + unexpected_arguments := call_expr.args[min_required_args..] + unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos) + c.error('expected $min_required_args arguments, but got $call_expr.args.len', + unexpected_arguments_pos) + return f.return_type } - for arg in call_expr.args { - c.expr(arg.expr) - } - return f.return_type - } - 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', - call_expr.pos) - } else if !f.is_variadic && call_expr.args.len > f.params.len { - unexpected_arguments := call_expr.args[min_required_args..] - unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos) - c.error('expected $min_required_args arguments, but got $call_expr.args.len', - 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 { @@ -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 diff --git a/vlib/v/checker/tests/c_fn_surplus_args.out b/vlib/v/checker/tests/c_fn_surplus_args.out index 9f470d920d..a462c8470d 100644 --- a/vlib/v/checker/tests/c_fn_surplus_args.out +++ b/vlib/v/checker/tests/c_fn_surplus_args.out @@ -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 | diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index b644621d26..8241c159da 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -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*/') } } diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 7c54e750f3..b13b837250 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -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()') diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index 9a846e8192..9384697a54 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -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