1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

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

This commit is contained in:
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 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 // ... 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) fn C.sqlite3_free(voidptr)

View File

@ -72,7 +72,7 @@ fn main() {
println('wkhtmltopdf_http_error_code: $error_code') println('wkhtmltopdf_http_error_code: $error_code')
if result { if result {
data := &charptr(0) data := &charptr(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 {
println('ERR: $err') 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.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 fn C.puts(byteptr) int
@ -56,7 +57,7 @@ fn C.fputs(str byteptr, stream &C.FILE) int
fn C.fflush(&C.FILE) int fn C.fflush(&C.FILE) int
// TODO define args in these functions // 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 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.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: // process execution, os.process:
fn C.getpid() int fn C.getpid() int
@ -94,25 +95,25 @@ fn C.setenv(charptr, charptr, int) int
fn C.unsetenv(charptr) 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.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 fn C.sigemptyset() int
@ -122,18 +123,20 @@ fn C.signal(signal int, handlercb voidptr) voidptr
fn C.mktime() int fn C.mktime() int
fn C.gettimeofday() int fn C.gettimeofday(tv &C.timeval, tz &C.timezone) int
[trusted] [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.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) // C.rand returns a pseudorandom integer from 0 (inclusive) to C.RAND_MAX (exclusive)
[trusted] [trusted]
@ -141,13 +144,13 @@ fn C.rand() int
// C.srand seeds the internal PRNG with the given value. // C.srand seeds the internal PRNG with the given value.
[trusted] [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] [trusted]
fn C.getchar() int fn C.getchar() int
@ -155,33 +158,33 @@ fn C.getchar() int
[trusted] [trusted]
fn C.strerror(int) charptr 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.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._fileno(int) int
fn C._get_osfhandle(fd int) C.intptr_t 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.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 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.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.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 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.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() voidptr
fn C.GetStdHandle(u32) voidptr fn C.GetStdHandle(u32) voidptr
@ -235,33 +238,33 @@ fn C.wprintf()
// fn C.setbuf() // fn C.setbuf()
fn C.setbuf(voidptr, charptr) 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 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.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 fn C._fullpath() int
@ -281,25 +284,26 @@ fn C.GetCommandLine() voidptr
fn C.LocalFree() 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.CloseHandle(voidptr) int
fn C.GetExitCodeProcess() fn C.GetExitCodeProcess(hProcess voidptr, lpExitCode &u32)
fn C.GetTickCount() i64 fn C.GetTickCount() i64
fn C.Sleep() fn C.Sleep(dwMilliseconds u32)
fn C.WSAStartup(u16, &voidptr) int fn C.WSAStartup(u16, &voidptr) int

View File

@ -20,7 +20,7 @@ struct WndClassEx {
h_icon_sm &u16 h_icon_sm &u16
} }
fn C.RegisterClassEx(class WndClassEx) int fn C.RegisterClassEx(class &WndClassEx) int
fn C.GetClipboardOwner() &C.HWND 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.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 fn C.SetClipboardData(uFormat u32, data voidptr) C.HANDLE
@ -174,8 +174,8 @@ pub fn (mut cb Clipboard) get_text() string {
C.CloseClipboard() C.CloseClipboard()
return '' return ''
} }
str := unsafe { string_from_wide(&u16(C.GlobalLock(h_data))) } str := unsafe { string_from_wide(&u16(C.GlobalLock(C.HGLOBAL(h_data)))) }
C.GlobalUnlock(h_data) C.GlobalUnlock(C.HGLOBAL(h_data))
return str return str
} }

View File

@ -25,45 +25,45 @@ struct C.Window {
fn C.XInitThreads() int 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.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() {} fn todo_del() {}
@ -404,7 +404,7 @@ fn read_property(d &C.Display, w C.Window, p C.Atom) Property {
if ret != 0 { if ret != 0 {
C.XFree(ret) 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) &actual_format, &nitems, &bytes_after, &ret)
read_bytes *= 2 read_bytes *= 2
if bytes_after == 0 { if bytes_after == 0 {

View File

@ -8,12 +8,12 @@ module rand
#flag darwin -framework Security #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. // read returns an array of `bytes_needed` random bytes read from the OS.
pub fn read(bytes_needed int) ?[]byte { pub fn read(bytes_needed int) ?[]byte {
mut buffer := []byte{ len: bytes_needed } 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 { if status != 0 {
return read_error return read_error
} }

View File

@ -5,9 +5,9 @@ pub const (
rtld_lazy = 0 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 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_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 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_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 fn C.mysql_store_result(mysql &C.MYSQL) &C.MYSQL_RES

View File

@ -11,10 +11,14 @@ enum Select {
pub enum SocketType { pub enum SocketType {
udp = C.SOCK_DGRAM udp = C.SOCK_DGRAM
tcp = C.SOCK_STREAM tcp = C.SOCK_STREAM
dgram = C.SOCK_DGRAM
stream = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET
} }
// SocketFamily are the available address families // SocketFamily are the available address families
pub enum SocketFamily { pub enum SocketFamily {
unix = C.AF_UNIX
inet = C.AF_INET inet = C.AF_INET
} }
@ -55,59 +59,71 @@ mut:
struct C.sockaddr_storage { 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 // defined in builtin
// fn C.read() int // fn C.read() int
// fn C.close() 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] [typedef]
pub struct C.fd_set {} pub struct C.fd_set {}

View File

@ -34,49 +34,52 @@ pub struct SSL {
pub struct SSL_METHOD { 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_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_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.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 fn C.SSL_shutdown(&C.SSL) int

View File

@ -157,7 +157,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(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 { if cstr == 0 {
return error('net.peer_ip: inet_ntop failed') 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_bool(.reuse_addr, true)?
s.set_option_int(.reuse_addr, 1) ? s.set_option_int(.reuse_addr, 1) ?
$if windows { $if windows {
t := true t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else { } $else {
socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ? 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_bool(.reuse_addr, true)?
s.set_option_int(.reuse_addr, 1) ? s.set_option_int(.reuse_addr, 1) ?
$if windows { $if windows {
t := true t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else { } $else {
socket_error(C.fcntl(sockfd, C.F_SETFL, C.fcntl(sockfd, C.F_GETFL) | C.O_NONBLOCK)) ? 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) ? s.set_option_bool(.reuse_addr, true) ?
$if windows { $if windows {
t := true t := u32(1) // true
socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ? socket_error(C.ioctlsocket(sockfd, fionbio, &t)) ?
} $else { } $else {
socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK)) ? socket_error(C.fcntl(sockfd, C.F_SETFD, C.O_NONBLOCK)) ?

View File

@ -8,11 +8,11 @@ enum Select {
} }
// SocketType are the available sockets // SocketType are the available sockets
enum SocketType { // enum SocketType {
dgram = C.SOCK_DGRAM // dgram = C.SOCK_DGRAM
stream = C.SOCK_STREAM // stream = C.SOCK_STREAM
seqpacket = C.SOCK_SEQPACKET // seqpacket = C.SOCK_SEQPACKET
} // }
struct C.sockaddr { struct C.sockaddr {
sa_family u16 sa_family u16
@ -44,43 +44,43 @@ mut:
struct C.sockaddr_storage { 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.WSAAddressToStringA() int
fn C.getsockname() int // fn C.getsockname() int
// defined in builtin // defined in builtin
// fn C.read() int // fn C.read() int
@ -88,15 +88,15 @@ fn C.getsockname() int
fn C.ioctlsocket() 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] [typedef]
struct C.fd_set {} struct C.fd_set {}

View File

@ -7,7 +7,7 @@ const (
error_ewouldblock = C.EWOULDBLOCK 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) fn C.strncpy(charptr, charptr, int)

View File

@ -41,7 +41,7 @@ fn error_code() int {
} }
fn new_stream_socket() ?StreamSocket { 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{ mut s := StreamSocket{
handle: sockfd handle: sockfd
} }

View File

@ -9,7 +9,7 @@ struct C.dirent {
fn C.readdir(voidptr) &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 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.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 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) h_input := C.GetStdHandle(C.STD_INPUT_HANDLE)
mut bytes_read := 0 mut bytes_read := 0
if is_atty(0) > 0 { if is_atty(0) > 0 {
x := C.ReadConsole(h_input, buf, max_line_chars * 2, C.LPDWORD(&bytes_read), x := C.ReadConsole(h_input, buf, max_line_chars * 2, &bytes_read, 0)
0)
if !x { if !x {
return tos(buf, 0) return tos(buf, 0)
} }

View File

@ -40,39 +40,48 @@ struct C.sockaddr_storage {
fn C.atoi() int 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.read() int
fn C.shutdown() int fn C.shutdown(socket int, how int) int
// fn C.close() 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 // fn C.write() int
struct C.picoev_loop { 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_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 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.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] [inline]
fn setup_sock(fd int) { fn setup_sock(fd int) {
on := 1 on := 1

View File

@ -11,18 +11,22 @@ module picohttpparser
struct C.phr_header { struct C.phr_header {
pub: pub:
name charptr name charptr
name_len int name_len int
value charptr value charptr
value_len int value_len int
} }
struct C.phr_header_t {} struct C.phr_header_t {}
fn C.phr_parse_request() 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_response() int
fn C.phr_parse_headers() int
fn C.phr_parse_request_path() 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_request_path_pipeline() 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.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( pret := C.phr_parse_request(
s.str, s.len, s.str, s.len,
&r.method, &method_len, &r.method.str, &method_len,
&r.path, &path_len, &r.path.str, &path_len,
&minor_version, &minor_version,
r.headers, &num_headers, r.headers, &num_headers,
0 0
@ -44,8 +44,8 @@ pub fn (mut r Request) parse_request_path(s string) int {
pret := C.phr_parse_request_path( pret := C.phr_parse_request_path(
s.str, s.len, s.str, s.len,
&r.method, &method_len, &r.method.str, &method_len,
&r.path, &path_len &r.path.str, &path_len
) )
if pret > 0 { if pret > 0 {
unsafe { unsafe {
@ -63,8 +63,8 @@ pub fn (mut r Request) parse_request_path_pipeline(s string) int {
pret := C.phr_parse_request_path_pipeline( pret := C.phr_parse_request_path_pipeline(
s.str, s.len, s.str, s.len,
&r.method, &method_len, &r.method.str, &method_len,
&r.path, &path_len &r.path.str, &path_len
) )
if pret > 0 { if pret > 0 {
unsafe { unsafe {

View File

@ -12,11 +12,11 @@ import os
#include <termios.h> #include <termios.h>
#include <sys/ioctl.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 fn C.getppid() int

View File

@ -1,6 +1,6 @@
module sfons module sfons
fn C.sfons_create(width int, height int, flags int) &C.FONScontext 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_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_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 fn C.sqlite3_step(&C.sqlite3_stmt) int

View File

@ -4,6 +4,7 @@ import os
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <termios.h> // TIOCGWINSZ #include <termios.h> // TIOCGWINSZ
pub struct C.winsize { pub struct C.winsize {
pub: pub:
ws_row u16 ws_row u16
@ -20,7 +21,7 @@ pub fn get_terminal_size() (int, int) {
return default_columns_size, default_rows_size return default_columns_size, default_rows_size
} }
w := C.winsize{} 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) return int(w.ws_col), int(w.ws_row)
} }
@ -52,7 +53,7 @@ pub fn get_cursor_position() Coord {
i++ i++
if i >= 15 { if i >= 15 {
panic('C.getchar() called too many times') panic('C.getchar() called too many times')
} }
// state management: // state management:
if b == `R` { if b == `R` {
break break

View File

@ -44,16 +44,16 @@ mut:
} }
// ref - https://docs.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo // 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 // ref - https://docs.microsoft.com/en-us/windows/console/setconsoletitle
fn C.SetConsoleTitle(title &u16) bool fn C.SetConsoleTitle(title &u16) bool
// ref - https://docs.microsoft.com/en-us/windows/console/setconsolecursorposition // 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 // 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. // get_terminal_size returns a number of colums and rows of terminal window.
pub fn get_terminal_size() (int, int) { pub fn get_terminal_size() (int, int) {

View File

@ -77,8 +77,8 @@ struct C.CONSOLE_SCREEN_BUFFER_INFO {
dwMaximumWindowSize C.COORD 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 <sys/ioctl.h>
#include <signal.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 fn C.ioctl(fd int, request u64, arg voidptr) int

View File

@ -17,10 +17,10 @@ struct C.tm {
tm_isdst int tm_isdst int
} }
fn C.timegm(&tm) time_t fn C.timegm(&C.tm) time_t
// fn C.gmtime_r(&tm, &gbuf) // 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 { fn make_unix_time(t C.tm) int {
return int(C.timegm(&t)) return int(C.timegm(&t))

View File

@ -29,11 +29,11 @@ struct SystemTime {
millisecond u16 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) 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.token
import v.ast 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_ mut expected := expected_
// variadic // variadic
if expected.has_flag(.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 exp_info := exp_type_sym.info as table.Array
expected = exp_info.elem_type 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) { if c.check_types(got, expected) {
return return
} }
@ -46,6 +79,17 @@ pub fn (mut c Checker) check_basic(got table.Type, expected table.Type) bool {
return true 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] { if exp_sym.kind in [.voidptr, .any] || got_sym.kind in [.voidptr, .any] {
return true 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_hi := type_hi.idx()
idx_lo := type_lo.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 { if idx_hi == table.int_literal_type_idx {
return type_lo return type_lo
} else if idx_hi == table.float_literal_type_idx { } 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 { if method.generic_names.len > 0 {
continue 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 // str method, allow type with str method if fn arg is string
// Passing an int or a string array produces a c error here // Passing an int or a string array produces a c error here
// Deleting this condition results in propper V error messages // 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 { && f.ctdefine !in c.pref.compile_defines {
call_expr.should_be_skipped = true call_expr.should_be_skipped = true
} }
if f.language != .v || call_expr.language != .v { // dont check number of args for JS functions since arguments are not required
// ignore C function of type `fn()`, assume untyped if call_expr.language != .js {
// For now don't check C functions that are variadic, underscored, capitalized min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len }
// or have no params or attributes and return int if call_expr.args.len < min_required_args {
if f.language == .c && f.params.len != call_expr.args.len && !f.is_variadic c.error('expected $min_required_args arguments, but got $call_expr.args.len',
&& f.name[2] != `_` && !f.name[2].is_capital() && (f.params.len != 0 call_expr.pos)
|| f.return_type !in [table.void_type, table.int_type] } else if !f.is_variadic && call_expr.args.len > f.params.len {
|| f.attrs.len > 0) { unexpected_arguments := call_expr.args[min_required_args..]
// change to error later unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos)
c.warn('expected $f.params.len arguments, but got $call_expr.args.len', call_expr.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 // println / eprintln / panic can print anything
if fn_name in ['println', 'print', 'eprintln', 'eprint', 'panic'] && call_expr.args.len > 0 { 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', c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block',
call_arg.pos) 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) to_lock, pos := c.fail_if_immutable(call_arg.expr)
if !arg.is_mut { if !arg.is_mut {
tok := call_arg.share.str() 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()) c.type_implements(typ, arg.typ, call_arg.expr.position())
continue 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 // str method, allow type with str method if fn arg is string
// Passing an int or a string array produces a c error here // Passing an int or a string array produces a c error here
// Deleting this condition results in propper V error messages // 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 vlib/v/checker/tests/c_fn_surplus_args.vv:7:4: error: expected 1 arguments, but got 0
5 | fn main() { 5 | fn main() {
6 | C.no(1) // allowed 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 8 | C.y1(1) // ok
9 | C.y1(1, 2) 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() 7 | C.y1()
8 | C.y1(1) // ok 8 | C.y1(1) // ok
9 | C.y1(1, 2) 9 | C.y1(1, 2)
| ~~~~~~~~ | ^
10 | C.ret() // ok 10 | C.ret() // ok
11 | C.ret(1) 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) 9 | C.y1(1, 2)
10 | C.ret() // ok 10 | C.ret() // ok
11 | C.ret(1) 11 | C.ret(1)
| ~~~~~~ | ^
12 | // avoid cgen whilst warning, later above should error 12 | // avoid cgen whilst warning, later above should error
13 | main() 13 | main()
vlib/v/checker/tests/c_fn_surplus_args.vv:13:2: error: the `main` function cannot be called in the program 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 14 | C.af() // ok
15 | C.af(3) 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() 13 | main()
14 | C.af() // ok 14 | C.af() // ok
15 | C.af(3) 15 | C.af(3)
| ~~~~~ | ^
16 | } 16 | }
17 | 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) { fn (mut g Gen) call_args(node ast.CallExpr) {
args := if g.is_js_call { node.args[1..] } else { node.args } args := if g.is_js_call { node.args[1..] } else { node.args }
expected_types := node.expected_arg_types expected_types := node.expected_arg_types
// only v variadic, C variadic args will be appeneded like normal args
is_variadic := expected_types.len > 0 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 { for i, arg in args {
if is_variadic && i == expected_types.len - 1 { if is_variadic && i == expected_types.len - 1 {
break break
@ -1024,7 +1025,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
g.write('/*af arg*/' + name) g.write('/*af arg*/' + name)
} }
} else { } else {
g.ref_or_deref_arg(arg, expected_types[i]) g.ref_or_deref_arg(arg, expected_types[i], node.language)
} }
} else { } else {
if use_tmp_var_autofree { if use_tmp_var_autofree {
@ -1054,7 +1055,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
if variadic_count > 0 { if variadic_count > 0 {
g.write('new_array_from_c_array($variadic_count, $variadic_count, sizeof($elem_type), _MOV(($elem_type[$variadic_count]){') 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 { 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 { if j < args.len - 1 {
g.write(', ') g.write(', ')
} }
@ -1068,7 +1069,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
} }
[inline] [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 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 expr_is_ptr := arg.typ.is_ptr() || arg.typ.idx() in table.pointer_type_idxs
if expected_type == 0 { 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 expected_type
} }
deref_sym := g.table.get_type_symbol(expected_deref_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*/') 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) { fn (mut g Gen) expr(node ast.Expr) {
// println('cgen expr()') // println('cgen expr()')

View File

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