mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check incorrect names
This commit is contained in:
parent
3bd88a3cc2
commit
f44a40eee0
@ -213,7 +213,7 @@ fn C.GetModuleFileNameW(hModule voidptr, lpFilename &u16, nSize u32) u32
|
||||
fn C.CreatePipe(hReadPipe &voidptr, hWritePipe &voidptr, lpPipeAttributes voidptr, nSize u32) bool
|
||||
|
||||
|
||||
fn C.SetHandleInformation(hObject voidptr, dwMask u32, dwFlags u32) bool
|
||||
fn C.SetHandleInformation(hObject voidptr, dwMask u32, dw_flags u32) bool
|
||||
|
||||
|
||||
fn C.ExpandEnvironmentStringsW(lpSrc &u16, lpDst &u16, nSize u32) u32
|
||||
@ -228,7 +228,7 @@ fn C.ReadFile(hFile voidptr, lpBuffer voidptr, nNumberOfBytesToRead u32, lpNumbe
|
||||
fn C.GetFileAttributesW(lpFileName byteptr) u32
|
||||
|
||||
|
||||
fn C.RegQueryValueExW(hKey voidptr, lpValueName &u16, lpReserved &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.RegOpenKeyExW(hKey voidptr, lpSubKey &u16, ulOptions u32, samDesired u32, phkResult voidptr) int
|
||||
|
@ -31,7 +31,6 @@ fn test_float_equal_operator() {
|
||||
assert a.gebit(1)
|
||||
assert -1 == 1 * -1
|
||||
assert -1.0 == 1.0 * -1.0
|
||||
|
||||
a = f64(1)
|
||||
a += 0.000001
|
||||
a -= 0.000001
|
||||
@ -47,7 +46,6 @@ fn test_float_equal_operator() {
|
||||
assert a.gtbit(f32(1))
|
||||
assert a >= 1
|
||||
assert a.gebit(1)
|
||||
|
||||
f := 1.2
|
||||
ab := int(f)
|
||||
assert ab == 1
|
||||
@ -62,7 +60,6 @@ fn test_str_methods() {
|
||||
assert int(-1).str() == '-1'
|
||||
assert i64(1).str() == '1'
|
||||
assert i64(-1).str() == '-1'
|
||||
|
||||
// assert byte(1).str() == '1'
|
||||
// assert byte(-1).str() == '255'
|
||||
assert u16(1).str() == '1'
|
||||
@ -131,17 +128,11 @@ fn test_cmp() {
|
||||
assert 1 ⩾ 0
|
||||
}
|
||||
*/
|
||||
|
||||
type myint int
|
||||
type mystring string
|
||||
type MyInt int
|
||||
|
||||
fn test_int_alias() {
|
||||
/*
|
||||
i := myint(2)
|
||||
s := mystring('hi')
|
||||
ss := s + '!'
|
||||
i := MyInt(2)
|
||||
assert i + 10 == 12
|
||||
*/
|
||||
}
|
||||
|
||||
fn test_hex() {
|
||||
@ -194,49 +185,43 @@ fn test_int_decl() {
|
||||
|
||||
fn test_int_to_hex() {
|
||||
// array hex
|
||||
st := [byte(`V`),`L`,`A`,`N`,`G`]
|
||||
assert st.hex() == "564c414e47"
|
||||
st := [byte(`V`), `L`, `A`, `N`, `G`]
|
||||
assert st.hex() == '564c414e47'
|
||||
assert st.hex().len == 10
|
||||
|
||||
st1 := [byte(0x41)].repeat(100)
|
||||
assert st1.hex() == "41".repeat(100)
|
||||
|
||||
//--- int to hex tests
|
||||
assert st1.hex() == '41'.repeat(100)
|
||||
// --- int to hex tests
|
||||
c0 := 12
|
||||
|
||||
// 8Bit
|
||||
assert byte(0).hex() == "0"
|
||||
assert byte(c0).hex() == "c"
|
||||
assert i8(c0).hex() == "c"
|
||||
assert byte(127).hex() == "7f"
|
||||
assert i8(127).hex() == "7f"
|
||||
assert byte(255).hex() == "ff"
|
||||
assert byte(-1).hex() == "ff"
|
||||
|
||||
assert byte(0).hex() == '0'
|
||||
assert byte(c0).hex() == 'c'
|
||||
assert i8(c0).hex() == 'c'
|
||||
assert byte(127).hex() == '7f'
|
||||
assert i8(127).hex() == '7f'
|
||||
assert byte(255).hex() == 'ff'
|
||||
assert byte(-1).hex() == 'ff'
|
||||
// 16bit
|
||||
assert u16(0).hex() == "0"
|
||||
assert i16(c0).hex() == "c"
|
||||
assert u16(c0).hex() == "c"
|
||||
assert i16(32767).hex() == "7fff"
|
||||
assert u16(32767).hex() == "7fff"
|
||||
assert i16(-1).hex() == "ffff"
|
||||
assert u16(65535).hex() == "ffff"
|
||||
|
||||
assert u16(0).hex() == '0'
|
||||
assert i16(c0).hex() == 'c'
|
||||
assert u16(c0).hex() == 'c'
|
||||
assert i16(32767).hex() == '7fff'
|
||||
assert u16(32767).hex() == '7fff'
|
||||
assert i16(-1).hex() == 'ffff'
|
||||
assert u16(65535).hex() == 'ffff'
|
||||
// 32bit
|
||||
assert u32(0).hex() == "0"
|
||||
assert c0.hex() == "c"
|
||||
assert u32(c0).hex() == "c"
|
||||
assert 2147483647.hex() == "7fffffff"
|
||||
assert u32(2147483647).hex() == "7fffffff"
|
||||
assert (-1).hex() == "ffffffff"
|
||||
assert u32(4294967295).hex() == "ffffffff"
|
||||
|
||||
assert u32(0).hex() == '0'
|
||||
assert c0.hex() == 'c'
|
||||
assert u32(c0).hex() == 'c'
|
||||
assert 2147483647.hex() == '7fffffff'
|
||||
assert u32(2147483647).hex() == '7fffffff'
|
||||
assert (-1).hex() == 'ffffffff'
|
||||
assert u32(4294967295).hex() == 'ffffffff'
|
||||
// 64 bit
|
||||
assert u64(0).hex() == "0"
|
||||
assert i64(c0).hex() == "c"
|
||||
assert u64(c0).hex() == "c"
|
||||
assert i64(9223372036854775807).hex() == "7fffffffffffffff"
|
||||
assert u64(9223372036854775807).hex() == "7fffffffffffffff"
|
||||
assert i64(-1).hex() == "ffffffffffffffff"
|
||||
assert u64(18446744073709551615).hex() == "ffffffffffffffff"
|
||||
assert u64(0).hex() == '0'
|
||||
assert i64(c0).hex() == 'c'
|
||||
assert u64(c0).hex() == 'c'
|
||||
assert i64(9223372036854775807).hex() == '7fffffffffffffff'
|
||||
assert u64(9223372036854775807).hex() == '7fffffffffffffff'
|
||||
assert i64(-1).hex() == 'ffffffffffffffff'
|
||||
assert u64(18446744073709551615).hex() == 'ffffffffffffffff'
|
||||
}
|
||||
|
@ -766,3 +766,12 @@ fn test_string_literal_with_backslash(){
|
||||
Three'
|
||||
assert b == 'OneTwoThree'
|
||||
}
|
||||
|
||||
/*
|
||||
type MyString string
|
||||
|
||||
fn test_string_alias() {
|
||||
s := MyString('hi')
|
||||
ss := s + '!'
|
||||
}
|
||||
*/
|
||||
|
@ -3,49 +3,62 @@ module clipboard
|
||||
import time
|
||||
|
||||
struct WndClassEx {
|
||||
cbSize u32
|
||||
style u32
|
||||
lpfnWndProc voidptr
|
||||
cbClsExtra int
|
||||
cbWndExtra int
|
||||
hInstance C.HINSTANCE
|
||||
hIcon C.HICON
|
||||
hCursor C.HCURSOR
|
||||
hbrBackground C.HBRUSH
|
||||
lpszMenuName &u16 // LPCWSTR
|
||||
lpszClassName &u16
|
||||
hIconSm &u16
|
||||
cb_size u32
|
||||
style u32
|
||||
lpfn_wnd_proc voidptr
|
||||
cb_cls_extra int
|
||||
cb_wnd_extra int
|
||||
h_instance C.HINSTANCE
|
||||
h_icon C.HICON
|
||||
h_cursor C.HCURSOR
|
||||
hbr_background C.HBRUSH
|
||||
lpsz_menu_name &u16 // LPCWSTR
|
||||
lpsz_class_name &u16
|
||||
h_icon_sm &u16
|
||||
}
|
||||
|
||||
fn C.RegisterClassEx(class WndClassEx) int
|
||||
|
||||
fn C.GetClipboardOwner() &C.HWND
|
||||
fn C.CreateWindowEx(dwExStyle i64, lpClassName &u16, lpWindowName &u16, dwStyle i64, x int, y int, nWidth int, nHeight int, hWndParent i64, hMenu voidptr, hInstance voidptr, lpParam voidptr) &C.HWND
|
||||
//fn C.MultiByteToWideChar(CodePage u32, dwFlags u16, lpMultiByteStr byteptr, cbMultiByte int, lpWideCharStr u16, cchWideChar int) int
|
||||
|
||||
fn C.CreateWindowEx(dwExStyle i64, lpClassName, lpWindowName &u16, dwStyle i64, x, y, nWidth, nHeight int, hWndParent i64, hMenu, h_instance, lpParam voidptr) &C.HWND
|
||||
|
||||
// fn C.MultiByteToWideChar(CodePage u32, dw_flags u16, lpMultiByteStr byteptr, cbMultiByte int, lpWideCharStr u16, cchWideChar int) int
|
||||
fn C.EmptyClipboard()
|
||||
|
||||
fn C.CloseClipboard()
|
||||
|
||||
fn C.GlobalAlloc(uFlag u32, size i64) C.HGLOBAL
|
||||
|
||||
fn C.GlobalFree(buf C.HGLOBAL)
|
||||
|
||||
fn C.GlobalLock(buf C.HGLOBAL)
|
||||
|
||||
fn C.GlobalUnlock(buf C.HGLOBAL)
|
||||
|
||||
fn C.SetClipboardData(uFormat u32, data voidptr) C.HANDLE
|
||||
|
||||
fn C.GetClipboardData(uFormat u32) C.HANDLE
|
||||
|
||||
fn C.DefWindowProc(hwnd C.HWND, msg u32, wParam C.WPARAM, lParam C.LPARAM) C.LRESULT
|
||||
|
||||
fn C.SetLastError(error i64)
|
||||
|
||||
fn C.OpenClipboard(hwnd C.HWND) int
|
||||
|
||||
fn C.DestroyWindow(hwnd C.HWND)
|
||||
|
||||
struct Clipboard {
|
||||
max_retries int
|
||||
retry_delay int
|
||||
mut:
|
||||
hwnd C.HWND
|
||||
foo int // TODO remove
|
||||
hwnd C.HWND
|
||||
foo int // TODO remove
|
||||
}
|
||||
|
||||
fn (cb &Clipboard) get_clipboard_lock() bool {
|
||||
mut retries := cb.max_retries
|
||||
mut last_error := u32(0)
|
||||
|
||||
for {
|
||||
retries--
|
||||
if retries < 0 {
|
||||
@ -57,7 +70,6 @@ fn (cb &Clipboard) get_clipboard_lock() bool {
|
||||
} else if last_error != u32(C.ERROR_ACCESS_DENIED) {
|
||||
return false
|
||||
}
|
||||
|
||||
time.sleep(cb.retry_delay)
|
||||
}
|
||||
C.SetLastError(last_error)
|
||||
@ -65,24 +77,25 @@ fn (cb &Clipboard) get_clipboard_lock() bool {
|
||||
}
|
||||
|
||||
fn new_clipboard() &Clipboard {
|
||||
mut cb := &Clipboard {
|
||||
mut cb := &Clipboard{
|
||||
max_retries: 5
|
||||
retry_delay: 5
|
||||
}
|
||||
class_name := "clipboard"
|
||||
wndclass := WndClassEx {
|
||||
cbSize: sizeof(WndClassEx)
|
||||
lpfnWndProc: voidptr(&C.DefWindowProc)
|
||||
lpszClassName: class_name.to_wide()
|
||||
lpszMenuName: 0
|
||||
hIconSm: 0
|
||||
class_name := 'clipboard'
|
||||
wndclass := WndClassEx{
|
||||
cb_size: sizeof(WndClassEx)
|
||||
lpfn_wnd_proc: voidptr(&C.DefWindowProc)
|
||||
lpsz_class_name: class_name.to_wide()
|
||||
lpsz_menu_name: 0
|
||||
h_icon_sm: 0
|
||||
}
|
||||
if C.RegisterClassEx(&wndclass) == 0 && C.GetLastError() != u32(C.ERROR_CLASS_ALREADY_EXISTS) {
|
||||
println("Failed registering class.")
|
||||
println('Failed registering class.')
|
||||
}
|
||||
hwnd := C.CreateWindowEx(0, wndclass.lpszClassName, wndclass.lpszClassName, 0, 0, 0, 0, 0, C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL)
|
||||
hwnd := C.CreateWindowEx(0, wndclass.lpsz_class_name, wndclass.lpsz_class_name, 0, 0, 0,
|
||||
0, 0, C.HWND_MESSAGE, C.NULL, C.NULL, C.NULL)
|
||||
if hwnd == C.NULL {
|
||||
println("Error creating window!")
|
||||
println('Error creating window!')
|
||||
}
|
||||
cb.hwnd = hwnd
|
||||
return cb
|
||||
@ -96,21 +109,24 @@ fn (cb &Clipboard) has_ownership() bool {
|
||||
return C.GetClipboardOwner() == cb.hwnd
|
||||
}
|
||||
|
||||
fn (cb mut Clipboard) clear() {
|
||||
if !cb.get_clipboard_lock() {return}
|
||||
fn (mut cb Clipboard) clear() {
|
||||
if !cb.get_clipboard_lock() {
|
||||
return
|
||||
}
|
||||
C.EmptyClipboard()
|
||||
C.CloseClipboard()
|
||||
cb.foo = 0
|
||||
}
|
||||
|
||||
fn (cb mut Clipboard) free(){
|
||||
fn (mut cb Clipboard) free() {
|
||||
C.DestroyWindow(cb.hwnd)
|
||||
cb.foo = 0
|
||||
}
|
||||
|
||||
// the string.to_wide doesn't work with SetClipboardData, don't know why
|
||||
fn to_wide(text string) &C.HGLOBAL {
|
||||
len_required := C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len + 1, C.NULL, 0)
|
||||
len_required := C.MultiByteToWideChar(C.CP_UTF8, C.MB_ERR_INVALID_CHARS, text.str, text.len +
|
||||
1, C.NULL, 0)
|
||||
buf := C.GlobalAlloc(C.GMEM_MOVEABLE, sizeof(u16) * len_required)
|
||||
if buf != C.HGLOBAL(C.NULL) {
|
||||
mut locked := &u16(C.GlobalLock(buf))
|
||||
@ -121,7 +137,7 @@ fn to_wide(text string) &C.HGLOBAL {
|
||||
return buf
|
||||
}
|
||||
|
||||
fn (cb mut Clipboard) set_text(text string) bool {
|
||||
fn (mut cb Clipboard) set_text(text string) bool {
|
||||
cb.foo = 0
|
||||
buf := to_wide(text)
|
||||
if !cb.get_clipboard_lock() {
|
||||
@ -131,7 +147,7 @@ fn (cb mut Clipboard) set_text(text string) bool {
|
||||
// EmptyClipboard must be called to properly update clipboard ownership
|
||||
C.EmptyClipboard()
|
||||
if C.SetClipboardData(C.CF_UNICODETEXT, buf) == C.HANDLE(C.NULL) {
|
||||
println("SetClipboardData: Failed.")
|
||||
println('SetClipboardData: Failed.')
|
||||
C.CloseClipboard()
|
||||
C.GlobalFree(buf)
|
||||
return false
|
||||
@ -142,15 +158,15 @@ fn (cb mut Clipboard) set_text(text string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
fn (cb mut Clipboard) get_text() string {
|
||||
fn (mut cb Clipboard) get_text() string {
|
||||
cb.foo = 0
|
||||
if !cb.get_clipboard_lock() {
|
||||
return ""
|
||||
return ''
|
||||
}
|
||||
h_data := C.GetClipboardData(C.CF_UNICODETEXT)
|
||||
if h_data == C.HANDLE(C.NULL) {
|
||||
C.CloseClipboard()
|
||||
return ""
|
||||
return ''
|
||||
}
|
||||
str := string_from_wide(&u16(C.GlobalLock(h_data)))
|
||||
C.GlobalUnlock(h_data)
|
||||
|
@ -164,27 +164,27 @@ fn utf8util_char_len(b byte) int {
|
||||
//
|
||||
// up_low make the dirt job
|
||||
fn up_low(s string, upper_flag bool) string {
|
||||
mut _index := 0
|
||||
mut index := 0
|
||||
mut str_res := malloc(s.len + 1)
|
||||
|
||||
for {
|
||||
ch_len := utf8util_char_len(s.str[_index])
|
||||
ch_len := utf8util_char_len(s.str[index])
|
||||
|
||||
if ch_len == 1 {
|
||||
if upper_flag==true {
|
||||
str_res[_index] = C.toupper(s.str[_index])
|
||||
str_res[index] = C.toupper(s.str[index])
|
||||
}else{
|
||||
str_res[_index] = C.tolower(s.str[_index])
|
||||
str_res[index] = C.tolower(s.str[index])
|
||||
}
|
||||
}
|
||||
else if ch_len > 1 && ch_len < 5{
|
||||
mut lword := 0
|
||||
|
||||
for i:=0; i < ch_len ; i++ {
|
||||
lword = (lword << 8 ) | int( s.str[_index + i] )
|
||||
lword = (lword << 8 ) | int( s.str[index + i] )
|
||||
}
|
||||
|
||||
//C.printf(" #%d (%x) ", _index, lword)
|
||||
//C.printf(" #%d (%x) ", index, lword)
|
||||
|
||||
mut res := 0
|
||||
|
||||
@ -215,7 +215,7 @@ fn up_low(s string, upper_flag bool) string {
|
||||
// char not in table, no need of conversion
|
||||
if ch_index == 0 {
|
||||
for i in 0..ch_len {
|
||||
str_res[_index + i] = s.str[_index + i]
|
||||
str_res[index + i] = s.str[index + i]
|
||||
}
|
||||
//C.printf("\n")
|
||||
}else{
|
||||
@ -227,13 +227,13 @@ fn up_low(s string, upper_flag bool) string {
|
||||
ch1 := byte( (tab_char >> 0) & 0x3f ) | 0x80 /*10xx xxxx*/
|
||||
//C.printf("[%02x%02x] \n",ch0,ch1)
|
||||
|
||||
str_res[ _index + 0 ] = ch0
|
||||
str_res[ _index + 1 ] = ch1
|
||||
str_res[ index + 0 ] = ch0
|
||||
str_res[ index + 1 ] = ch1
|
||||
|
||||
//****************************************************************
|
||||
// BUG: doesn't compile, workaround use shitf to right of 0 bit
|
||||
//****************************************************************
|
||||
//str_res[_index + 1 ] = byte( tab_char & 0xbf ) /*1011 1111*/
|
||||
//str_res[index + 1 ] = byte( tab_char & 0xbf ) /*1011 1111*/
|
||||
|
||||
}
|
||||
else if ch_len == 3 {
|
||||
@ -242,16 +242,16 @@ fn up_low(s string, upper_flag bool) string {
|
||||
ch2 := byte( (tab_char >> 0) & 0x3f ) | 0x80 /*10xx xxxx*/
|
||||
//C.printf("[%02x%02x%02x] \n",ch0,ch1,ch2)
|
||||
|
||||
str_res[_index + 0 ] = ch0
|
||||
str_res[_index + 1 ] = ch1
|
||||
str_res[_index + 2 ] = ch2
|
||||
str_res[index + 0 ] = ch0
|
||||
str_res[index + 1 ] = ch1
|
||||
str_res[index + 2 ] = ch2
|
||||
}
|
||||
// TODO: write if needed
|
||||
else if ch_len == 4 {
|
||||
// place holder!!
|
||||
// at the present time simply copy the utf8 char
|
||||
for i in 0..ch_len {
|
||||
str_res[_index + i] = s.str[_index + i]
|
||||
str_res[index + i] = s.str[index + i]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,20 +260,20 @@ fn up_low(s string, upper_flag bool) string {
|
||||
// other cases, just copy the string
|
||||
else{
|
||||
for i in 0..ch_len {
|
||||
str_res[_index + i] = s.str[_index + i]
|
||||
str_res[index + i] = s.str[index + i]
|
||||
}
|
||||
}
|
||||
|
||||
_index += ch_len
|
||||
index += ch_len
|
||||
|
||||
// we are done, exit the loop
|
||||
if _index >= s.len {
|
||||
if index >= s.len {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// for c compatibility set the ending 0
|
||||
str_res[_index]=0
|
||||
str_res[index]=0
|
||||
|
||||
//C.printf("str_res: %s\n--------------\n",str_res)
|
||||
|
||||
@ -1680,6 +1680,6 @@ unicode_punct=[
|
||||
0x1DA8A, // SIGNWRITING COLON 𝪊
|
||||
0x1DA8B, // SIGNWRITING PARENTHESIS 𝪋
|
||||
0x1E95E, // ADLAM INITIAL EXCLAMATION MARK 𞥞
|
||||
0x1E95F, // ADLAM INITIAL QUESTION MARK
|
||||
0x1E95F, // ADLAM INITIAL QUESTION MARK
|
||||
]
|
||||
)
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Copyright (c) 2019-2020 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
module freetype
|
||||
|
||||
import os
|
||||
@ -9,19 +8,17 @@ import gx
|
||||
import gg
|
||||
import glm
|
||||
import gl
|
||||
|
||||
/*
|
||||
TODO
|
||||
!!!!!!
|
||||
Use a font atlas
|
||||
!!!!!!
|
||||
*/
|
||||
|
||||
#flag windows -I @VROOT/thirdparty/freetype/include
|
||||
#flag windows -L @VROOT/thirdparty/freetype/win64
|
||||
|
||||
#flag solaris -I/opt/local/include/freetype2
|
||||
#flag solaris -L/opt/local/lib
|
||||
|
||||
#flag darwin -I/usr/local/include/freetype2
|
||||
// MacPorts
|
||||
#flag darwin -I/opt/local/include/freetype2
|
||||
@ -29,49 +26,39 @@ Use a font atlas
|
||||
#flag freebsd -I/usr/local/include/freetype2
|
||||
#flag freebsd -Wl -L/usr/local/lib
|
||||
#flag -lfreetype
|
||||
|
||||
//#flag -I @VROOT/thirdparty/freetype
|
||||
|
||||
//#flag @VROOT/thirdparty/freetype/libfreetype.a
|
||||
// #flag -I @VROOT/thirdparty/freetype
|
||||
// #flag @VROOT/thirdparty/freetype/libfreetype.a
|
||||
#flag darwin -lpng -lbz2 -lz
|
||||
|
||||
|
||||
#flag linux -I/usr/include/freetype2
|
||||
#flag linux -I.
|
||||
|
||||
|
||||
#include "ft2build.h"
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
fn C.FT_Init_FreeType() voidptr
|
||||
|
||||
fn C.FT_New_Face() voidptr
|
||||
|
||||
fn C.FT_Set_Pixel_Sizes()
|
||||
|
||||
|
||||
|
||||
pub const (
|
||||
default_font_size = 12
|
||||
)
|
||||
|
||||
struct Character {
|
||||
code i64
|
||||
|
||||
texture_id u32
|
||||
size gg.Vec2
|
||||
|
||||
code i64
|
||||
texture_id u32
|
||||
size gg.Vec2
|
||||
horizontal_bearing_px gg.Vec2
|
||||
horizontal_advance_px u32
|
||||
|
||||
vertical_bearing_px gg.Vec2
|
||||
vertical_advance_px u32
|
||||
}
|
||||
|
||||
[typedef]
|
||||
struct C.FT_Library {}
|
||||
struct C.FT_Library {
|
||||
}
|
||||
|
||||
pub struct FreeType {
|
||||
shader gl.Shader
|
||||
// use_ortho bool
|
||||
width int
|
||||
height int
|
||||
vao u32
|
||||
@ -89,8 +76,8 @@ mut:
|
||||
}
|
||||
|
||||
struct C.Bitmap {
|
||||
width int
|
||||
rows int
|
||||
width int
|
||||
rows int
|
||||
buffer int
|
||||
}
|
||||
|
||||
@ -112,42 +99,43 @@ struct C.FT_Glyph_Metrics {
|
||||
}
|
||||
|
||||
struct C.Glyph {
|
||||
bitmap C.Bitmap
|
||||
bitmap C.Bitmap
|
||||
bitmap_left int
|
||||
bitmap_top int
|
||||
advance Advance
|
||||
metrics C.FT_Glyph_Metrics
|
||||
bitmap_top int
|
||||
advance Advance
|
||||
metrics C.FT_Glyph_Metrics
|
||||
}
|
||||
|
||||
[typedef]
|
||||
struct C.FT_FaceRec {
|
||||
glyph &C.Glyph
|
||||
glyph &C.Glyph
|
||||
family_name charptr
|
||||
style_name charptr
|
||||
style_name charptr
|
||||
}
|
||||
///type FT_Face &C.FT_FaceRec
|
||||
|
||||
// /type FT_Face &C.FT_FaceRec
|
||||
fn C.FT_Load_Char(voidptr, i64, int) int
|
||||
|
||||
fn ft_load_char(face &C.FT_FaceRec, code i64) Character {
|
||||
//println('\nftload_char( code=$code)')
|
||||
//C.printf('face=%p\n', face)
|
||||
//C.printf('cobj=%p\n', _face.cobj)
|
||||
ret := C.FT_Load_Char(face, code, C.FT_LOAD_RENDER|C.FT_LOAD_FORCE_AUTOHINT)
|
||||
//println('ret=$ret')
|
||||
// println('\nftload_char( code=$code)')
|
||||
// C.printf('face=%p\n', face)
|
||||
// C.printf('cobj=%p\n', _face.cobj)
|
||||
ret := C.FT_Load_Char(face, code, C.FT_LOAD_RENDER | C.FT_LOAD_FORCE_AUTOHINT)
|
||||
// println('ret=$ret')
|
||||
if ret != 0 {
|
||||
println('freetype: failed to load glyph (utf32 code=$code, ' +
|
||||
'error code=$ret)')
|
||||
return Character{code: code}
|
||||
println('freetype: failed to load glyph (utf32 code=$code, ' + 'error code=$ret)')
|
||||
return Character{
|
||||
code: code
|
||||
}
|
||||
}
|
||||
// Generate texture
|
||||
mut texture := 0
|
||||
C.glGenTextures(1, &texture)
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, texture)
|
||||
fgwidth := (*face).glyph.bitmap.width
|
||||
fgrows := (*face).glyph.bitmap.rows
|
||||
C.glTexImage2D(C.GL_TEXTURE_2D, 0, C.GL_RED, fgwidth, fgrows,
|
||||
0, C.GL_RED, C.GL_UNSIGNED_BYTE, (*face).glyph.bitmap.buffer)
|
||||
fgrows := (*face).glyph.bitmap.rows
|
||||
C.glTexImage2D(C.GL_TEXTURE_2D, 0, C.GL_RED, fgwidth, fgrows, 0, C.GL_RED, C.GL_UNSIGNED_BYTE,
|
||||
(*face).glyph.bitmap.buffer)
|
||||
// Set texture options
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_WRAP_S, C.GL_CLAMP_TO_EDGE)
|
||||
C.glTexParameteri(C.GL_TEXTURE_2D, C.GL_TEXTURE_WRAP_T, C.GL_CLAMP_TO_EDGE)
|
||||
@ -173,7 +161,9 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
scale := cfg.scale
|
||||
// Can only have text in ortho mode
|
||||
if !cfg.use_ortho {
|
||||
return &FreeType{face:0}
|
||||
return &FreeType{
|
||||
face: 0
|
||||
}
|
||||
}
|
||||
width := cfg.width * scale
|
||||
height := cfg.height * scale
|
||||
@ -193,7 +183,7 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
C.glBlendFunc(C.GL_SRC_ALPHA, C.GL_ONE_MINUS_SRC_ALPHA)
|
||||
shader := gl.new_shader('text')
|
||||
shader.use()
|
||||
projection := glm.ortho(0, width, 0, height)// 0 at BOT
|
||||
projection := glm.ortho(0, width, 0, height) // 0 at BOT
|
||||
shader.set_mat4('projection', projection)
|
||||
// FREETYPE
|
||||
ft := C.FT_Library{}
|
||||
@ -215,9 +205,11 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
eprintln('freetype: font "$font_path" does not exist')
|
||||
return 0
|
||||
}
|
||||
face := &C.FT_FaceRec{glyph:0}
|
||||
face := &C.FT_FaceRec{
|
||||
glyph: 0
|
||||
}
|
||||
ret = int(C.FT_New_Face(ft, font_path.str, 0, &face))
|
||||
if ret != 0 {
|
||||
if ret != 0 {
|
||||
eprintln('freetype: failed to load font (error=$ret) from path: $font_path')
|
||||
exit(1)
|
||||
}
|
||||
@ -228,7 +220,7 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
// Gen texture
|
||||
// Load first 128 characters of ASCII set
|
||||
mut chars := []Character{}
|
||||
for c in 0..128 {
|
||||
for c in 0 .. 128 {
|
||||
ch := ft_load_char(face, i64(c))
|
||||
// s := utf32_to_str(uint(0x043f))
|
||||
// s := 'п'
|
||||
@ -240,10 +232,10 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
// # ch = gg__ft_load_char(f, 0xd0bf) ; // UTF 8
|
||||
chars << ch
|
||||
}
|
||||
//ch := Character{}
|
||||
// ch := Character{}
|
||||
// Configure VAO
|
||||
vao := gl.gen_vertex_array()
|
||||
//println('new gg text context vao=$vao')
|
||||
// println('new gg text context vao=$vao')
|
||||
vbo := gl.gen_buffer()
|
||||
gl.bind_vao(vao)
|
||||
gl.bind_buffer(C.GL_ARRAY_BUFFER, vbo)
|
||||
@ -253,7 +245,7 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
// # glVertexAttribPointer(0, 4, GL_FLOAT,false, 4 * sizeof(GLf32), 0);
|
||||
// gl.bind_buffer(GL_ARRAY_BUFFER, uint(0))
|
||||
// # glBindVertexArray(0);
|
||||
ctx := &FreeType {
|
||||
ctx := &FreeType{
|
||||
shader: shader
|
||||
width: width
|
||||
height: height
|
||||
@ -263,21 +255,21 @@ pub fn new_context(cfg gg.Cfg) &FreeType {
|
||||
chars: chars
|
||||
face: face
|
||||
}
|
||||
//ctx.init_utf8_runes()
|
||||
// ctx.init_utf8_runes()
|
||||
return ctx
|
||||
}
|
||||
|
||||
pub fn (ctx mut FreeType) draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
||||
//utext := text.ustring_tmp()
|
||||
pub fn (mut ctx FreeType) draw_text(_x, _y int, text string, cfg gx.TextCfg) {
|
||||
// utext := text.ustring_tmp()
|
||||
utext := text.ustring()
|
||||
ctx.private_draw_text(_x, _y, utext, cfg)
|
||||
}
|
||||
|
||||
fn (ctx mut FreeType) draw_text_fast(_x, _y int, text ustring, cfg gx.TextCfg) {
|
||||
fn (mut ctx FreeType) draw_text_fast(_x, _y int, text ustring, cfg gx.TextCfg) {
|
||||
ctx.private_draw_text(_x, _y, text, cfg)
|
||||
}
|
||||
|
||||
fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
|
||||
fn (mut ctx FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCfg) {
|
||||
/*
|
||||
if utext.s.contains('on_seg') {
|
||||
println('\nat(0)')
|
||||
@ -295,14 +287,14 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||
yoffset := if ctx.scale > 1 { 5 } else { -1 } // 5 hidpi, -1 lowdpi
|
||||
// println('scale=$ctx.scale size=$cfg.size')
|
||||
if cfg.align == gx.ALIGN_RIGHT {
|
||||
//width := utext.len * 7
|
||||
// width := utext.len * 7
|
||||
width := wx
|
||||
x -= width + 10
|
||||
}
|
||||
x *= ctx.scale
|
||||
y *= ctx.scale
|
||||
y += yoffset
|
||||
y = f32(ctx.height) - y //invert y direction
|
||||
y = f32(ctx.height) - y // invert y direction
|
||||
color := cfg.color
|
||||
// Activate corresponding render state
|
||||
ctx.shader.use()
|
||||
@ -311,25 +303,24 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||
gl.bind_vao(ctx.vao)
|
||||
// Iterate through all characters
|
||||
// utext := text.ustring()
|
||||
for i in 0..utext.len {
|
||||
_rune := utext.at(i)
|
||||
// println('$i => $_rune')
|
||||
for i in 0 .. utext.len {
|
||||
rune_ := utext.at(i)
|
||||
// println('$i => $rune_')
|
||||
mut ch := Character{}
|
||||
mut found := false
|
||||
if _rune.len == 1 {
|
||||
idx := _rune[0]
|
||||
if rune_.len == 1 {
|
||||
idx := rune_[0]
|
||||
if idx < 0 || idx >= ctx.chars.len {
|
||||
println('BADE RUNE $_rune')
|
||||
println('BADE RUNE $rune_')
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
ch = ctx.chars[_rune[0]]
|
||||
}
|
||||
else if _rune.len > 1 {
|
||||
ch = ctx.chars[rune_[0]]
|
||||
} else if rune_.len > 1 {
|
||||
// TODO O(1) use map
|
||||
for j in 0..ctx.utf_runes.len {
|
||||
for j in 0 .. ctx.utf_runes.len {
|
||||
rune_j := ctx.utf_runes[j]
|
||||
if rune_j==_rune {
|
||||
if rune_j == rune_ {
|
||||
ch = ctx.utf_chars[j]
|
||||
found = true
|
||||
break
|
||||
@ -337,31 +328,30 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||
}
|
||||
}
|
||||
// A new Unicode character. Load it and cache it.
|
||||
if !found && _rune.len > 0 && _rune[0] > 32 {
|
||||
//c := _rune[0]
|
||||
//println('cant draw rune "$_rune" code=$c, loading')
|
||||
//continue
|
||||
ch = ft_load_char(ctx.face, _rune.utf32_code())
|
||||
//println('done loading')
|
||||
ctx.utf_runes << _rune
|
||||
if !found && rune_.len > 0 && rune_[0] > 32 {
|
||||
// c := rune_[0]
|
||||
// println('cant draw rune "$rune_" code=$c, loading')
|
||||
// continue
|
||||
ch = ft_load_char(ctx.face, rune_.utf32_code())
|
||||
// println('done loading')
|
||||
ctx.utf_runes << rune_
|
||||
ctx.utf_chars << ch
|
||||
//exit(1)
|
||||
// exit(1)
|
||||
// continue
|
||||
}
|
||||
xpos := x + f32(ch.horizontal_bearing_px.x) * 1
|
||||
ypos := y - f32(ch.size.y + wy - ch.horizontal_bearing_px.y) * 1
|
||||
//ypos := y - wy
|
||||
// ypos := y - wy
|
||||
w := f32(ch.size.x) * 1
|
||||
h := f32(ch.size.y) * 1
|
||||
// Update VBO for each character
|
||||
vertices := [
|
||||
xpos, ypos + h, 0.0, 0.0 ,
|
||||
xpos, ypos, 0.0, 1.0 ,
|
||||
xpos + w, ypos, 1.0, 1.0 ,
|
||||
xpos, ypos + h, 0.0, 0.0 ,
|
||||
xpos + w, ypos, 1.0, 1.0 ,
|
||||
xpos + w, ypos + h, 1.0, 0.0
|
||||
]
|
||||
vertices := [
|
||||
xpos, ypos + h, 0.0, 0.0,
|
||||
xpos, ypos, 0.0, 1.0,
|
||||
xpos + w, ypos, 1.0, 1.0,
|
||||
xpos, ypos + h, 0.0, 0.0,
|
||||
xpos + w, ypos, 1.0, 1.0,
|
||||
xpos + w, ypos + h, 1.0, 0.0]
|
||||
// Render glyph texture over quad
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, ch.texture_id)
|
||||
// Update content of VBO memory
|
||||
@ -372,9 +362,9 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||
gl.draw_arrays(C.GL_TRIANGLES, 0, 6)
|
||||
x += f32(ch.horizontal_advance_px)
|
||||
// Stop drawing if the limit is reached
|
||||
if cfg.max_width > 0 {
|
||||
if cfg.max_width > 0 {
|
||||
if x >= cfg.max_width {
|
||||
//break
|
||||
// break
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,8 +372,8 @@ fn (ctx mut FreeType) private_draw_text(_x, _y int, utext ustring, cfg gx.TextCf
|
||||
C.glBindTexture(C.GL_TEXTURE_2D, 0)
|
||||
}
|
||||
|
||||
pub fn (ctx mut FreeType) draw_text_def(x, y int, text string) {
|
||||
cfg := gx.TextCfg {
|
||||
pub fn (mut ctx FreeType) draw_text_def(x, y int, text string) {
|
||||
cfg := gx.TextCfg{
|
||||
color: gx.Black
|
||||
size: default_font_size
|
||||
align: gx.align_left
|
||||
@ -391,50 +381,49 @@ pub fn (ctx mut FreeType) draw_text_def(x, y int, text string) {
|
||||
ctx.draw_text(x, y, text, cfg)
|
||||
}
|
||||
|
||||
pub fn (ctx mut FreeType) text_width(s string) int {
|
||||
pub fn (mut ctx FreeType) text_width(s string) int {
|
||||
x, _ := ctx.text_size(s)
|
||||
return x
|
||||
}
|
||||
|
||||
pub fn (ctx mut FreeType) text_height(s string) int {
|
||||
pub fn (mut ctx FreeType) text_height(s string) int {
|
||||
_, y := ctx.text_size(s)
|
||||
return y
|
||||
}
|
||||
|
||||
pub fn (ctx mut FreeType) text_size(s string) (int, int) {
|
||||
//t := time.ticks()
|
||||
pub fn (mut ctx FreeType) text_size(s string) (int, int) {
|
||||
// t := time.ticks()
|
||||
utext := s.ustring()
|
||||
mut x := u32(0)
|
||||
mut maxy := u32(0)
|
||||
mut _rune := ''
|
||||
mut rune_ := ''
|
||||
mut ch := Character{}
|
||||
for i in 0..utext.len {
|
||||
_rune = utext.at(i)
|
||||
for i in 0 .. utext.len {
|
||||
rune_ = utext.at(i)
|
||||
ch = Character{}
|
||||
mut found := false
|
||||
if _rune.len == 1 {
|
||||
idx := _rune[0]
|
||||
if rune_.len == 1 {
|
||||
idx := rune_[0]
|
||||
if idx < 0 || idx >= ctx.chars.len {
|
||||
println('BADE RUNE $_rune')
|
||||
println('BADE RUNE $rune_')
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
ch = ctx.chars[_rune[0]]
|
||||
}
|
||||
else if _rune.len > 1 {
|
||||
ch = ctx.chars[rune_[0]]
|
||||
} else if rune_.len > 1 {
|
||||
// TODO O(1) use map
|
||||
for j in 0..ctx.utf_runes.len {
|
||||
for j in 0 .. ctx.utf_runes.len {
|
||||
rune_j := ctx.utf_runes[j]
|
||||
if rune_j==_rune {
|
||||
if rune_j == rune_ {
|
||||
ch = ctx.utf_chars[j]
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if !found && _rune.len > 0 && _rune[0] > 32 {
|
||||
ch = ft_load_char(ctx.face, _rune.utf32_code())
|
||||
ctx.utf_runes << _rune
|
||||
if !found && rune_.len > 0 && rune_[0] > 32 {
|
||||
ch = ft_load_char(ctx.face, rune_.utf32_code())
|
||||
ctx.utf_runes << rune_
|
||||
ctx.utf_chars << ch
|
||||
}
|
||||
x += ch.horizontal_advance_px
|
||||
@ -442,12 +431,12 @@ pub fn (ctx mut FreeType) text_size(s string) (int, int) {
|
||||
maxy = ch.vertical_advance_px
|
||||
}
|
||||
}
|
||||
//println('text width "$s" = ${time.ticks() - t} ms')
|
||||
//scaled_x := x
|
||||
//scaled_y := maxy
|
||||
scaled_x := int(f64(x)/ctx.scale)
|
||||
scaled_y := int(f64(maxy)/ctx.scale)
|
||||
//println('text_size of "${s}" | x,y: $x,$maxy | scaled_x: ${scaled_x:3d} | scaled_y: ${scaled_y:3d} ')
|
||||
// println('text width "$s" = ${time.ticks() - t} ms')
|
||||
// scaled_x := x
|
||||
// scaled_y := maxy
|
||||
scaled_x := int(f64(x) / ctx.scale)
|
||||
scaled_y := int(f64(maxy) / ctx.scale)
|
||||
// println('text_size of "${s}" | x,y: $x,$maxy | scaled_x: ${scaled_x:3d} | scaled_y: ${scaled_y:3d} ')
|
||||
return scaled_x, scaled_y
|
||||
}
|
||||
|
||||
@ -456,7 +445,6 @@ pub fn (f FT_Face) str() string {
|
||||
return 'FT_Face{ style_name: ${ptr_str(f.style_name)} family_name: ${ptr_str(f.family_name)} }'
|
||||
}
|
||||
*/
|
||||
|
||||
pub fn (ac []Character) str() string {
|
||||
mut res := []string{}
|
||||
for c in ac {
|
||||
|
@ -122,7 +122,7 @@ pub:
|
||||
}
|
||||
|
||||
// type clickpub fn pub fn (window * GLFWwindow, button, action, mods int)
|
||||
type clickpubfn fn (window voidptr, button, action, mods int)
|
||||
type ClickPubFn fn (window voidptr, button, action, mods int)
|
||||
|
||||
/*
|
||||
* TODO broken
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
basic ftp module
|
||||
basic ftp module
|
||||
RFC-959
|
||||
https://tools.ietf.org/html/rfc959
|
||||
|
||||
@ -15,29 +15,28 @@
|
||||
dtp.close()
|
||||
ftp.close()
|
||||
*/
|
||||
|
||||
module ftp
|
||||
|
||||
import net
|
||||
|
||||
const (
|
||||
Connected = 220
|
||||
SpecifyPassword = 331
|
||||
LoggedIn = 230
|
||||
LoginFirst = 503
|
||||
Anonymous = 530
|
||||
OpenDataConnection = 150
|
||||
Connected = 220
|
||||
SpecifyPassword = 331
|
||||
LoggedIn = 230
|
||||
LoginFirst = 503
|
||||
Anonymous = 530
|
||||
OpenDataConnection = 150
|
||||
CloseDataConnection = 226
|
||||
CommandOk = 200
|
||||
denied = 550
|
||||
PassiveMode = 227
|
||||
complete = 226
|
||||
CommandOk = 200
|
||||
denied = 550
|
||||
PassiveMode = 227
|
||||
complete = 226
|
||||
)
|
||||
|
||||
struct DTP {
|
||||
mut:
|
||||
sock net.Socket
|
||||
ip string
|
||||
ip string
|
||||
port int
|
||||
}
|
||||
|
||||
@ -45,24 +44,27 @@ fn (dtp DTP) read() []byte {
|
||||
mut data := []byte{}
|
||||
for {
|
||||
buf, len := dtp.sock.recv(1024)
|
||||
if len == 0 { break }
|
||||
|
||||
for i in 0..len {
|
||||
if len == 0 {
|
||||
break
|
||||
}
|
||||
for i in 0 .. len {
|
||||
data << buf[i]
|
||||
}
|
||||
unsafe { free(buf) }
|
||||
unsafe {
|
||||
free(buf)
|
||||
}
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
fn (dtp DTP) close() {
|
||||
dtp.sock.close() or {}
|
||||
dtp.sock.close() or {
|
||||
}
|
||||
}
|
||||
|
||||
struct FTP {
|
||||
mut:
|
||||
sock net.Socket
|
||||
sock net.Socket
|
||||
buffer_size int
|
||||
}
|
||||
|
||||
@ -87,11 +89,9 @@ fn (ftp FTP) read() (int, string) {
|
||||
$if debug {
|
||||
println('FTP.v <<< $data')
|
||||
}
|
||||
|
||||
if data.len < 5 {
|
||||
return 0, ''
|
||||
}
|
||||
|
||||
code := data[..3].int()
|
||||
if data[3] == `-` {
|
||||
for {
|
||||
@ -101,21 +101,18 @@ fn (ftp FTP) read() (int, string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return code, data
|
||||
}
|
||||
|
||||
pub fn (ftp mut FTP) connect(ip string) bool {
|
||||
pub fn (mut ftp FTP) connect(ip string) bool {
|
||||
sock := net.dial(ip, 21) or {
|
||||
return false
|
||||
}
|
||||
ftp.sock = sock
|
||||
|
||||
code, _ := ftp.read()
|
||||
if code == Connected {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
@ -126,36 +123,34 @@ pub fn (ftp FTP) login(user, passwd string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
mut code, data := ftp.read()
|
||||
if code == LoggedIn {
|
||||
return true
|
||||
}
|
||||
|
||||
if code != SpecifyPassword {
|
||||
return false
|
||||
}
|
||||
|
||||
ftp.write('PASS $passwd') or {
|
||||
$if debug {
|
||||
println('ERROR sending password')
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
code, data = ftp.read()
|
||||
|
||||
// TODO Replace `data` with `_`
|
||||
_ := data
|
||||
if code == LoggedIn {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
pub fn (ftp FTP) close() {
|
||||
send_quit := 'QUIT\r\n'
|
||||
ftp.sock.send_string(send_quit) or {}
|
||||
ftp.sock.close() or {}
|
||||
ftp.sock.send_string(send_quit) or {
|
||||
}
|
||||
ftp.sock.close() or {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (ftp FTP) pwd() string {
|
||||
@ -171,7 +166,9 @@ pub fn (ftp FTP) pwd() string {
|
||||
}
|
||||
|
||||
pub fn (ftp FTP) cd(dir string) {
|
||||
ftp.write('CWD $dir') or { return }
|
||||
ftp.write('CWD $dir') or {
|
||||
return
|
||||
}
|
||||
mut code, mut data := ftp.read()
|
||||
match int(code) {
|
||||
denied {
|
||||
@ -184,7 +181,6 @@ pub fn (ftp FTP) cd(dir string) {
|
||||
}
|
||||
else {}
|
||||
}
|
||||
|
||||
$if debug {
|
||||
println('CD $data')
|
||||
}
|
||||
@ -194,14 +190,11 @@ fn new_dtp(msg string) ?DTP {
|
||||
if !is_dtp_message_valid(msg) {
|
||||
return error('Bad message')
|
||||
}
|
||||
|
||||
ip, port := get_host_ip_from_dtp_message(msg)
|
||||
|
||||
sock := net.dial(ip, port) or {
|
||||
return error('Cannot connect to the data channel')
|
||||
}
|
||||
|
||||
dtp := DTP {
|
||||
dtp := DTP{
|
||||
sock: sock
|
||||
ip: ip
|
||||
port: port
|
||||
@ -210,18 +203,17 @@ fn new_dtp(msg string) ?DTP {
|
||||
}
|
||||
|
||||
fn (ftp FTP) pasv() ?DTP {
|
||||
ftp.write('PASV') or {}
|
||||
ftp.write('PASV') or {
|
||||
}
|
||||
code, data := ftp.read()
|
||||
$if debug {
|
||||
println('pass: $data')
|
||||
}
|
||||
|
||||
if code != PassiveMode {
|
||||
return error('pasive mode not allowed')
|
||||
}
|
||||
|
||||
dtp := new_dtp(data) or {
|
||||
return error(err)
|
||||
return error(err)
|
||||
}
|
||||
return dtp
|
||||
}
|
||||
@ -230,8 +222,8 @@ pub fn (ftp FTP) dir() ?[]string {
|
||||
dtp := ftp.pasv() or {
|
||||
return error('cannot establish data connection')
|
||||
}
|
||||
|
||||
ftp.write('LIST') or {}
|
||||
ftp.write('LIST') or {
|
||||
}
|
||||
code, _ := ftp.read()
|
||||
if code == denied {
|
||||
return error('LIST denied')
|
||||
@ -239,23 +231,20 @@ pub fn (ftp FTP) dir() ?[]string {
|
||||
if code != OpenDataConnection {
|
||||
return error('data channel empty')
|
||||
}
|
||||
|
||||
list_dir := dtp.read()
|
||||
result, _ := ftp.read()
|
||||
if result != CloseDataConnection {
|
||||
println('LIST not ok')
|
||||
}
|
||||
dtp.close()
|
||||
|
||||
mut dir := []string{}
|
||||
sdir := string(byteptr(list_dir.data))
|
||||
for lfile in sdir.split('\n') {
|
||||
if lfile.len >1 {
|
||||
if lfile.len > 1 {
|
||||
spl := lfile.split(' ')
|
||||
dir << spl[spl.len-1]
|
||||
dir << spl[spl.len - 1]
|
||||
}
|
||||
}
|
||||
|
||||
return dir
|
||||
}
|
||||
|
||||
@ -263,21 +252,17 @@ pub fn (ftp FTP) get(file string) ?[]byte {
|
||||
dtp := ftp.pasv() or {
|
||||
return error('Cannot stablish data connection')
|
||||
}
|
||||
|
||||
ftp.write('RETR $file') or {}
|
||||
ftp.write('RETR $file') or {
|
||||
}
|
||||
code, _ := ftp.read()
|
||||
|
||||
if code == denied {
|
||||
return error('Permission denied')
|
||||
}
|
||||
|
||||
if code != OpenDataConnection {
|
||||
return error('Data connection not ready')
|
||||
}
|
||||
|
||||
blob := dtp.read()
|
||||
dtp.close()
|
||||
|
||||
return blob
|
||||
}
|
||||
|
||||
@ -290,7 +275,6 @@ fn is_dtp_message_valid(msg string) bool {
|
||||
fn get_host_ip_from_dtp_message(msg string) (string, int) {
|
||||
mut par_start_idx := -1
|
||||
mut par_end_idx := -1
|
||||
|
||||
for i, c in msg {
|
||||
if c == `(` {
|
||||
par_start_idx = i + 1
|
||||
@ -299,9 +283,7 @@ fn get_host_ip_from_dtp_message(msg string) (string, int) {
|
||||
}
|
||||
}
|
||||
data := msg[par_start_idx..par_end_idx].split(',')
|
||||
|
||||
ip := data[0..4].join('.')
|
||||
port := data[4].int() * 256 + data[5].int()
|
||||
|
||||
return ip, port
|
||||
}
|
||||
|
@ -57,11 +57,11 @@ pub fn read_set_cookies(h map[string][]string) []&Cookie {
|
||||
continue
|
||||
}
|
||||
name := keyval[0]
|
||||
_value := keyval[1]
|
||||
raw_value := keyval[1]
|
||||
if !is_cookie_name_valid(name) {
|
||||
continue
|
||||
}
|
||||
value := parse_cookie_value(_value, true) or {
|
||||
value := parse_cookie_value(raw_value, true) or {
|
||||
continue
|
||||
}
|
||||
mut c := &Cookie{
|
||||
@ -75,14 +75,14 @@ pub fn read_set_cookies(h map[string][]string) []&Cookie {
|
||||
continue
|
||||
}
|
||||
mut attr := parts[i]
|
||||
mut _val := ''
|
||||
mut raw_val := ''
|
||||
if attr.contains('=') {
|
||||
pieces := attr.split('=')
|
||||
attr = pieces[0]
|
||||
_val = pieces[1]
|
||||
raw_val = pieces[1]
|
||||
}
|
||||
lower_attr := attr.to_lower()
|
||||
val := parse_cookie_value(_val, false) or {
|
||||
val := parse_cookie_value(raw_val, false) or {
|
||||
c.unparsed << parts[i]
|
||||
continue
|
||||
}
|
||||
@ -158,9 +158,9 @@ pub fn read_cookies(h map[string][]string, filter string) []&Cookie {
|
||||
mut part := ''
|
||||
for line.len > 0 {
|
||||
if line.index_any(';') > 0 {
|
||||
_parts := line.split(';')
|
||||
part = _parts[0]
|
||||
line = _parts[1]
|
||||
line_parts := line.split(';')
|
||||
part = line_parts[0]
|
||||
line = line_parts[1]
|
||||
} else {
|
||||
part = line
|
||||
line = ''
|
||||
@ -172,9 +172,9 @@ pub fn read_cookies(h map[string][]string, filter string) []&Cookie {
|
||||
mut name := part
|
||||
mut val := ''
|
||||
if part.contains('=') {
|
||||
_parts := part.split('=')
|
||||
name = _parts[0]
|
||||
val = _parts[1]
|
||||
val_parts := part.split('=')
|
||||
name = val_parts[0]
|
||||
val = val_parts[1]
|
||||
}
|
||||
if !is_cookie_name_valid(name) {
|
||||
continue
|
||||
@ -182,12 +182,9 @@ pub fn read_cookies(h map[string][]string, filter string) []&Cookie {
|
||||
if filter != '' && filter != name {
|
||||
continue
|
||||
}
|
||||
// Circumvent the issue with assigning an `or` expression to an existing value
|
||||
// TODO: Fix when fixed in compiler
|
||||
_val := parse_cookie_value(val, true) or {
|
||||
val = parse_cookie_value(val, true) or {
|
||||
continue
|
||||
}
|
||||
val = _val
|
||||
cookies << &Cookie{name: name, value: val}
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,14 @@
|
||||
// that can be found in the LICENSE file.
|
||||
module http
|
||||
|
||||
type downloadfn fn(written int)type download_finished_fn fn()
|
||||
type DownloadFn = fn (written int)
|
||||
|
||||
/*
|
||||
struct DownloadStruct {
|
||||
mut:
|
||||
stream voidptr
|
||||
written int
|
||||
cb downloadfn
|
||||
cb DownloadFn
|
||||
}
|
||||
*/
|
||||
fn download_cb(ptr voidptr, size, nmemb size_t, userp voidptr) {
|
||||
@ -23,7 +24,7 @@ fn download_cb(ptr voidptr, size, nmemb size_t, userp voidptr) {
|
||||
*/
|
||||
}
|
||||
|
||||
pub fn download_file_with_progress(url, out string, cb downloadfn, cb_finished fn()) {
|
||||
pub fn download_file_with_progress(url, out string, cb DownloadFn, cb_finished fn()) {
|
||||
/*
|
||||
curl := C.curl_easy_init()
|
||||
if isnil(curl) {
|
||||
@ -49,4 +50,3 @@ pub fn download_file_with_progress(url, out string, cb downloadfn, cb_finished f
|
||||
|
||||
fn empty() {
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ import net.urllib
|
||||
import net.http.chunked
|
||||
|
||||
const (
|
||||
max_redirects = 4
|
||||
max_redirects = 4
|
||||
content_type_default = 'text/plain'
|
||||
)
|
||||
|
||||
@ -20,7 +20,6 @@ pub mut:
|
||||
url string
|
||||
user_agent string
|
||||
verbose bool
|
||||
//mut:
|
||||
user_ptr voidptr
|
||||
ws_func voidptr
|
||||
}
|
||||
@ -32,8 +31,8 @@ pub mut:
|
||||
params map[string]string
|
||||
headers map[string]string
|
||||
cookies map[string]string
|
||||
user_agent string//='v' QTODO
|
||||
verbose bool=false
|
||||
user_agent string // ='v' QTODO
|
||||
verbose bool = false
|
||||
}
|
||||
|
||||
pub struct Response {
|
||||
@ -44,9 +43,9 @@ pub:
|
||||
status_code int
|
||||
}
|
||||
|
||||
pub fn new_request(method, url_, data string) ?Request{
|
||||
pub fn new_request(method, url_, data string) ?Request {
|
||||
url := if method == 'GET' { url_ + '?' + data } else { url_ }
|
||||
//println('new req() method=$method url="$url" dta="$data"')
|
||||
// println('new req() method=$method url="$url" dta="$data"')
|
||||
return Request{
|
||||
method: method.to_upper()
|
||||
url: url
|
||||
@ -147,7 +146,7 @@ pub fn url_encode_form_data(data map[string]string) string {
|
||||
return pieces.join('&')
|
||||
}
|
||||
|
||||
fn fetch_with_method(method string, url string, _config FetchConfig) ?Response {
|
||||
fn fetch_with_method(method, url string, _config FetchConfig) ?Response {
|
||||
mut config := _config
|
||||
config.method = method
|
||||
return fetch(url, config)
|
||||
@ -173,21 +172,21 @@ fn build_url_from_fetch(_url string, config FetchConfig) ?string {
|
||||
return url.str()
|
||||
}
|
||||
|
||||
fn (req mut Request) free() {
|
||||
fn (mut req Request) free() {
|
||||
req.headers.free()
|
||||
}
|
||||
|
||||
fn (resp mut Response) free() {
|
||||
fn (mut resp Response) free() {
|
||||
resp.headers.free()
|
||||
}
|
||||
|
||||
// add_header adds the key and value of an HTTP request header
|
||||
pub fn (req mut Request) add_header(key, val string) {
|
||||
pub fn (mut req Request) add_header(key, val string) {
|
||||
req.headers[key] = val
|
||||
}
|
||||
|
||||
pub fn parse_headers(lines []string) map[string]string {
|
||||
mut headers := map[string]string
|
||||
mut headers := map[string]string{}
|
||||
for i, line in lines {
|
||||
if i == 0 {
|
||||
continue
|
||||
@ -258,8 +257,7 @@ fn (req &Request) method_and_url_to_response(method string, url urllib.URL) ?Res
|
||||
return error(err)
|
||||
}
|
||||
return res
|
||||
}
|
||||
else if scheme == 'http' {
|
||||
} else if scheme == 'http' {
|
||||
// println('http_do( $nport, $method, $host_name, $path )')
|
||||
res := req.http_do(nport, method, host_name, path) or {
|
||||
return error(err)
|
||||
@ -271,9 +269,9 @@ fn (req &Request) method_and_url_to_response(method string, url urllib.URL) ?Res
|
||||
|
||||
fn parse_response(resp string) Response {
|
||||
// TODO: Header data type
|
||||
mut headers := map[string]string
|
||||
mut headers := map[string]string{}
|
||||
// TODO: Cookie data type
|
||||
mut cookies := map[string]string
|
||||
mut cookies := map[string]string{}
|
||||
first_header := resp.all_before('\n')
|
||||
mut status_code := 0
|
||||
if first_header.contains('HTTP/') {
|
||||
@ -341,7 +339,8 @@ fn (req &Request) build_request_headers(method, host_name, path string) string {
|
||||
uheaders << '${key}: ${val}\r\n'
|
||||
}
|
||||
uheaders << req.build_request_cookies_header()
|
||||
return '$method $path HTTP/1.1\r\n' + uheaders.join('') + 'Connection: close\r\n\r\n' + req.data
|
||||
return '$method $path HTTP/1.1\r\n' + uheaders.join('') + 'Connection: close\r\n\r\n' +
|
||||
req.data
|
||||
}
|
||||
|
||||
fn (req &Request) build_request_cookies_header() string {
|
||||
@ -373,5 +372,3 @@ pub fn unescape(s string) string {
|
||||
pub fn escape(s string) string {
|
||||
panic('http.escape() was replaced with http.escape_url()')
|
||||
}
|
||||
|
||||
type wsfn fn(s string, ptr voidptr)
|
||||
|
@ -7,7 +7,7 @@ module net
|
||||
struct C.WSAData {
|
||||
mut:
|
||||
wVersion u16
|
||||
wHighVersion u16
|
||||
wHighVersion u16
|
||||
szDescription [257]byte
|
||||
szSystemStatus [129]byte
|
||||
iMaxSockets u16
|
||||
|
@ -6,7 +6,7 @@ pub struct Socket {
|
||||
pub:
|
||||
sockfd int
|
||||
family int
|
||||
_type int
|
||||
typ int
|
||||
proto int
|
||||
}
|
||||
|
||||
@ -39,53 +39,39 @@ struct C.sockaddr_storage {
|
||||
|
||||
fn C.socket() int
|
||||
|
||||
|
||||
fn C.setsockopt() int
|
||||
|
||||
|
||||
fn C.htonl() int
|
||||
|
||||
|
||||
fn C.htons() int
|
||||
|
||||
|
||||
fn C.bind() int
|
||||
|
||||
|
||||
fn C.listen() int
|
||||
|
||||
|
||||
fn C.accept() int
|
||||
|
||||
|
||||
fn C.getaddrinfo() int
|
||||
|
||||
|
||||
fn C.connect() int
|
||||
|
||||
|
||||
fn C.send() int
|
||||
|
||||
|
||||
fn C.recv() int
|
||||
|
||||
|
||||
fn C.read() int
|
||||
|
||||
|
||||
fn C.shutdown() int
|
||||
|
||||
|
||||
fn C.close() int
|
||||
|
||||
|
||||
fn C.ntohs() int
|
||||
|
||||
|
||||
fn C.getsockname() int
|
||||
|
||||
// create socket
|
||||
pub fn new_socket(family int, _type int, proto int) ?Socket {
|
||||
sockfd := C.socket(family, _type, proto)
|
||||
pub fn new_socket(family, typ, proto int) ?Socket {
|
||||
sockfd := C.socket(family, typ, proto)
|
||||
one := 1
|
||||
// This is needed so that there are no problems with reusing the
|
||||
// same port after the application exits.
|
||||
@ -96,7 +82,7 @@ pub fn new_socket(family int, _type int, proto int) ?Socket {
|
||||
s := Socket{
|
||||
sockfd: sockfd
|
||||
family: family
|
||||
_type: _type
|
||||
typ: typ
|
||||
proto: proto
|
||||
}
|
||||
return s
|
||||
@ -107,7 +93,7 @@ pub fn socket_udp() ?Socket {
|
||||
}
|
||||
|
||||
// set socket options
|
||||
pub fn (s Socket) setsockopt(level int, optname int, optvalue &int) ?int {
|
||||
pub fn (s Socket) setsockopt(level, optname int, optvalue &int) ?int {
|
||||
res := C.setsockopt(s.sockfd, level, optname, optvalue, sizeof(&int))
|
||||
if res < 0 {
|
||||
return error('net.setsocketopt: failed with $res')
|
||||
@ -117,8 +103,7 @@ pub fn (s Socket) setsockopt(level int, optname int, optvalue &int) ?int {
|
||||
|
||||
// bind socket to port
|
||||
pub fn (s Socket) bind(port int) ?int {
|
||||
mut addr := C.sockaddr_in{
|
||||
}
|
||||
mut addr := C.sockaddr_in{}
|
||||
addr.sin_family = s.family
|
||||
addr.sin_port = C.htons(port)
|
||||
addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
|
||||
@ -178,8 +163,7 @@ pub fn (s Socket) accept() ?Socket {
|
||||
$if debug {
|
||||
println('accept()')
|
||||
}
|
||||
addr := C.sockaddr_storage{
|
||||
}
|
||||
addr := C.sockaddr_storage{}
|
||||
size := 128 // sizeof(sockaddr_storage)
|
||||
sockfd := C.accept(s.sockfd, &addr, &size)
|
||||
if sockfd < 0 {
|
||||
@ -188,7 +172,7 @@ pub fn (s Socket) accept() ?Socket {
|
||||
c := Socket{
|
||||
sockfd: sockfd
|
||||
family: s.family
|
||||
_type: s._type
|
||||
typ: s.typ
|
||||
proto: s.proto
|
||||
}
|
||||
return c
|
||||
@ -196,10 +180,9 @@ pub fn (s Socket) accept() ?Socket {
|
||||
|
||||
// connect to given addrress and port
|
||||
pub fn (s Socket) connect(address string, port int) ?int {
|
||||
mut hints := C.addrinfo{
|
||||
}
|
||||
mut hints := C.addrinfo{}
|
||||
hints.ai_family = s.family
|
||||
hints.ai_socktype = s._type
|
||||
hints.ai_socktype = s.typ
|
||||
hints.ai_flags = C.AI_PASSIVE
|
||||
hints.ai_protocol = s.proto
|
||||
hints.ai_addrlen = 0
|
||||
@ -210,12 +193,12 @@ pub fn (s Socket) connect(address string, port int) ?int {
|
||||
sport := '$port'
|
||||
info_res := C.getaddrinfo(address.str, sport.str, &hints, &info)
|
||||
if info_res != 0 {
|
||||
error_message := os.get_error_msg(net.error_code())
|
||||
error_message := os.get_error_msg(error_code())
|
||||
return error('net.connect: getaddrinfo failed "$error_message"')
|
||||
}
|
||||
res := C.connect(s.sockfd, info.ai_addr, info.ai_addrlen)
|
||||
if res < 0 {
|
||||
error_message := os.get_error_msg(net.error_code())
|
||||
error_message := os.get_error_msg(error_code())
|
||||
return error('net.connect: connect failed "$error_message"')
|
||||
}
|
||||
return res
|
||||
@ -256,11 +239,13 @@ pub fn (s Socket) send_string(sdata string) ?int {
|
||||
}
|
||||
|
||||
// receive string data from socket. NB: you are responsible for freeing the returned byteptr
|
||||
pub fn (s Socket) recv(bufsize int) (byteptr,int) {
|
||||
pub fn (s Socket) recv(bufsize int) (byteptr, int) {
|
||||
mut buf := byteptr(0)
|
||||
unsafe { buf = malloc(bufsize) }
|
||||
unsafe {
|
||||
buf = malloc(bufsize)
|
||||
}
|
||||
res := C.recv(s.sockfd, buf, bufsize, 0)
|
||||
return buf,res
|
||||
return buf, res
|
||||
}
|
||||
|
||||
// TODO: remove cread/2 and crecv/2 when the Go net interface is done
|
||||
@ -300,10 +285,11 @@ pub fn (s Socket) close() ?int {
|
||||
}
|
||||
|
||||
pub const (
|
||||
CRLF = '\r\n'
|
||||
CRLF = '\r\n'
|
||||
MAX_READ = 400
|
||||
MSG_PEEK = 0x02
|
||||
)
|
||||
|
||||
// write - write a string with CRLF after it over the socket s
|
||||
pub fn (s Socket) write(str string) ?int {
|
||||
line := '$str$CRLF'
|
||||
@ -329,7 +315,7 @@ pub fn (s Socket) read_line() string {
|
||||
}
|
||||
buf[n] = `\0`
|
||||
mut eol_idx := -1
|
||||
for i in 0..n {
|
||||
for i in 0 .. n {
|
||||
if int(buf[i]) == `\n` {
|
||||
eol_idx = i
|
||||
// Ensure that tos_clone(buf) later,
|
||||
@ -377,8 +363,7 @@ pub fn (s Socket) read_all() string {
|
||||
}
|
||||
|
||||
pub fn (s Socket) get_port() int {
|
||||
mut addr := C.sockaddr_in{
|
||||
}
|
||||
mut addr := C.sockaddr_in{}
|
||||
size := 16 // sizeof(sockaddr_in)
|
||||
C.getsockname(s.sockfd, &addr, &size)
|
||||
return C.ntohs(addr.sin_port)
|
||||
|
10
vlib/os/os.v
10
vlib/os/os.v
@ -148,9 +148,9 @@ fn C.CopyFile(&u32, &u32, int) int
|
||||
// TODO implement actual cp for linux
|
||||
pub fn cp(old, new string) ?bool {
|
||||
$if windows {
|
||||
_old := old.replace('/', '\\')
|
||||
_new := new.replace('/', '\\')
|
||||
C.CopyFile(_old.to_wide(), _new.to_wide(), false)
|
||||
w_old := old.replace('/', '\\')
|
||||
w_new := new.replace('/', '\\')
|
||||
C.CopyFile(w_old.to_wide(), w_new.to_wide(), false)
|
||||
result := C.GetLastError()
|
||||
if result == 0 {
|
||||
return true
|
||||
@ -954,8 +954,8 @@ pub fn dir_exists(path string) bool {
|
||||
// is_dir returns a boolean indicating whether the given path is a directory.
|
||||
pub fn is_dir(path string) bool {
|
||||
$if windows {
|
||||
_path := path.replace('/', '\\')
|
||||
attr := C.GetFileAttributesW(_path.to_wide())
|
||||
w_path := path.replace('/', '\\')
|
||||
attr := C.GetFileAttributesW(w_path.to_wide())
|
||||
if attr == u32(C.INVALID_FILE_ATTRIBUTES) {
|
||||
return false
|
||||
}
|
||||
|
@ -16,64 +16,64 @@ pub type HANDLE voidptr
|
||||
// win: FILETIME
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
|
||||
struct Filetime {
|
||||
dwLowDateTime u32
|
||||
dwHighDateTime u32
|
||||
dw_low_date_time u32
|
||||
dw_high_date_time u32
|
||||
}
|
||||
|
||||
// win: WIN32_FIND_DATA
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-_win32_find_dataw
|
||||
struct Win32finddata {
|
||||
mut:
|
||||
dwFileAttributes u32
|
||||
ftCreationTime Filetime
|
||||
ftLastAccessTime Filetime
|
||||
ftLastWriteTime Filetime
|
||||
nFileSizeHigh u32
|
||||
nFileSizeLow u32
|
||||
dwReserved0 u32
|
||||
dwReserved1 u32
|
||||
cFileName [260]u16 // MAX_PATH = 260
|
||||
cAlternateFileName [14]u16 // 14
|
||||
dwFileType u32
|
||||
dwCreatorType u32
|
||||
wFinderFlags u16
|
||||
dw_file_attributes u32
|
||||
ft_creation_time Filetime
|
||||
ft_last_access_time Filetime
|
||||
ft_last_write_time Filetime
|
||||
n_file_size_high u32
|
||||
n_file_size_low u32
|
||||
dw_reserved0 u32
|
||||
dw_reserved1 u32
|
||||
c_file_name [260]u16 // MAX_PATH = 260
|
||||
c_alternate_file_name [14]u16 // 14
|
||||
dw_file_type u32
|
||||
dw_creator_type u32
|
||||
w_finder_flags u16
|
||||
}
|
||||
|
||||
struct ProcessInformation {
|
||||
mut:
|
||||
hProcess voidptr
|
||||
hThread voidptr
|
||||
dwProcessId u32
|
||||
dwThreadId u32
|
||||
h_process voidptr
|
||||
h_thread voidptr
|
||||
dw_process_id u32
|
||||
dw_thread_id u32
|
||||
}
|
||||
|
||||
struct StartupInfo {
|
||||
mut:
|
||||
cb u32
|
||||
lpReserved &u16
|
||||
lpDesktop &u16
|
||||
lpTitle &u16
|
||||
dwX u32
|
||||
dwY u32
|
||||
dwXSize u32
|
||||
dwYSize u32
|
||||
dwXCountChars u32
|
||||
dwYCountChars u32
|
||||
dwFillAttribute u32
|
||||
dwFlags u32
|
||||
wShowWindow u16
|
||||
cbReserved2 u16
|
||||
lpReserved2 byteptr
|
||||
hStdInput voidptr
|
||||
hStdOutput voidptr
|
||||
hStdError voidptr
|
||||
lp_reserved &u16
|
||||
lp_desktop &u16
|
||||
lp_title &u16
|
||||
dw_x u32
|
||||
dw_y u32
|
||||
dw_x_size u32
|
||||
dw_y_size u32
|
||||
dw_x_count_chars u32
|
||||
dw_y_count_chars u32
|
||||
dw_fill_attributes u32
|
||||
dw_flags u32
|
||||
w_show_window u16
|
||||
cb_reserved2 u16
|
||||
lp_reserved2 byteptr
|
||||
h_std_input voidptr
|
||||
h_std_output voidptr
|
||||
h_std_error voidptr
|
||||
}
|
||||
|
||||
struct SecurityAttributes {
|
||||
mut:
|
||||
nLength u32
|
||||
lpSecurityDescriptor voidptr
|
||||
bInheritHandle bool
|
||||
n_length u32
|
||||
lp_security_descriptor voidptr
|
||||
b_inherit_handle bool
|
||||
}
|
||||
|
||||
fn init_os_args_wide(argc int, argv &byteptr) []string {
|
||||
@ -102,12 +102,12 @@ pub fn ls(path string) ?[]string {
|
||||
// NOTE:TODO: once we have a way to convert utf16 wide character to utf8
|
||||
// we should use FindFirstFileW and FindNextFileW
|
||||
h_find_files := C.FindFirstFile(path_files.to_wide(), voidptr(&find_file_data))
|
||||
first_filename := string_from_wide(&u16(find_file_data.cFileName))
|
||||
first_filename := string_from_wide(&u16(find_file_data.c_file_name))
|
||||
if first_filename != '.' && first_filename != '..' {
|
||||
dir_files << first_filename
|
||||
}
|
||||
for C.FindNextFile(h_find_files, voidptr(&find_file_data)) > 0 {
|
||||
filename := string_from_wide(&u16(find_file_data.cFileName))
|
||||
filename := string_from_wide(&u16(find_file_data.c_file_name))
|
||||
if filename != '.' && filename != '..' {
|
||||
dir_files << filename.clone()
|
||||
}
|
||||
@ -186,12 +186,12 @@ pub fn mkdir(path string) ?bool {
|
||||
// get_file_handle retrieves the operating-system file handle that is associated with the specified file descriptor.
|
||||
pub fn get_file_handle(path string) HANDLE {
|
||||
mode := 'rb'
|
||||
_fd := C._wfopen(path.to_wide(), mode.to_wide())
|
||||
if _fd == 0 {
|
||||
fd := C._wfopen(path.to_wide(), mode.to_wide())
|
||||
if fd == 0 {
|
||||
return HANDLE(INVALID_HANDLE_VALUE)
|
||||
}
|
||||
_handle := HANDLE(C._get_osfhandle(C._fileno(_fd))) // CreateFile? - hah, no -_-
|
||||
return _handle
|
||||
handle := HANDLE(C._get_osfhandle(C._fileno(fd))) // CreateFile? - hah, no -_-
|
||||
return handle
|
||||
}
|
||||
|
||||
// Ref - https://docs.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-getmodulefilenamea
|
||||
@ -205,8 +205,7 @@ pub fn get_module_filename(handle HANDLE) ?string {
|
||||
status := int(C.GetModuleFileNameW(handle, voidptr(&buf), sz))
|
||||
match status {
|
||||
success {
|
||||
_filename := string_from_wide2(buf, sz)
|
||||
return _filename
|
||||
return string_from_wide2(buf, sz)
|
||||
}
|
||||
else {
|
||||
// Must handled with GetLastError and converted by FormatMessage
|
||||
@ -261,11 +260,11 @@ pub fn get_error_msg(code int) string {
|
||||
if code < 0 { // skip negative
|
||||
return ''
|
||||
}
|
||||
_ptr_text := ptr_win_get_error_msg(u32(code))
|
||||
if _ptr_text == 0 { // compare with null
|
||||
ptr_text := ptr_win_get_error_msg(u32(code))
|
||||
if ptr_text == 0 { // compare with null
|
||||
return ''
|
||||
}
|
||||
return string_from_wide(_ptr_text)
|
||||
return string_from_wide(ptr_text)
|
||||
}
|
||||
|
||||
// exec starts the specified command, waits for it to complete, and returns its output.
|
||||
@ -277,8 +276,8 @@ pub fn exec(cmd string) ?Result {
|
||||
mut child_stdout_read := &u32(0)
|
||||
mut child_stdout_write := &u32(0)
|
||||
mut sa := SecurityAttributes {}
|
||||
sa.nLength = sizeof(C.SECURITY_ATTRIBUTES)
|
||||
sa.bInheritHandle = true
|
||||
sa.n_length = sizeof(C.SECURITY_ATTRIBUTES)
|
||||
sa.b_inherit_handle = true
|
||||
|
||||
create_pipe_ok := C.CreatePipe(voidptr(&child_stdout_read),
|
||||
voidptr(&child_stdout_write), voidptr(&sa), 0)
|
||||
@ -294,14 +293,14 @@ pub fn exec(cmd string) ?Result {
|
||||
|
||||
proc_info := ProcessInformation{}
|
||||
start_info := StartupInfo{
|
||||
lpReserved: 0
|
||||
lpDesktop: 0
|
||||
lpTitle: 0
|
||||
lp_reserved: 0
|
||||
lp_desktop: 0
|
||||
lp_title: 0
|
||||
cb: sizeof(C.PROCESS_INFORMATION)
|
||||
hStdInput: child_stdin
|
||||
hStdOutput: child_stdout_write
|
||||
hStdError: child_stdout_write
|
||||
dwFlags: u32(C.STARTF_USESTDHANDLES)
|
||||
h_std_input: child_stdin
|
||||
h_std_output: child_stdout_write
|
||||
h_std_error: child_stdout_write
|
||||
dw_flags: u32(C.STARTF_USESTDHANDLES)
|
||||
}
|
||||
command_line := [32768]u16
|
||||
C.ExpandEnvironmentStringsW(cmd.to_wide(), voidptr(&command_line), 32768)
|
||||
@ -325,10 +324,10 @@ pub fn exec(cmd string) ?Result {
|
||||
soutput := read_data.str().trim_space()
|
||||
read_data.free()
|
||||
exit_code := u32(0)
|
||||
C.WaitForSingleObject(proc_info.hProcess, C.INFINITE)
|
||||
C.GetExitCodeProcess(proc_info.hProcess, voidptr(&exit_code))
|
||||
C.CloseHandle(proc_info.hProcess)
|
||||
C.CloseHandle(proc_info.hThread)
|
||||
C.WaitForSingleObject(proc_info.h_process, C.INFINITE)
|
||||
C.GetExitCodeProcess(proc_info.h_process, voidptr(&exit_code))
|
||||
C.CloseHandle(proc_info.h_process)
|
||||
C.CloseHandle(proc_info.h_thread)
|
||||
return Result {
|
||||
output: soutput
|
||||
exit_code: int(exit_code)
|
||||
|
@ -151,15 +151,13 @@ fn process_in_thread(pool mut PoolProcessor, task_id int) {
|
||||
// return *(&T(pool.items[idx]))
|
||||
//}
|
||||
|
||||
// TODO: the below is a hack, remove it when v2 &string() casting works again
|
||||
type mystring string
|
||||
// get_string_item - called by the worker callback.
|
||||
// It does not use generics so it does not mess up vfmt.
|
||||
// TODO: remove the need for this when vfmt becomes smarter.
|
||||
pub fn (pool &PoolProcessor) get_string_item(idx int) string {
|
||||
// return *(&string(pool.items[idx]))
|
||||
// TODO: the below is a hack, remove it when v2 casting works again
|
||||
return &mystring( pool.items[idx] )
|
||||
return &string( pool.items[idx] )
|
||||
}
|
||||
|
||||
// get_int_item - called by the worker callback.
|
||||
|
@ -8,18 +8,18 @@ struct Coord {
|
||||
}
|
||||
|
||||
struct SmallRect {
|
||||
Left i16
|
||||
Top i16
|
||||
Right i16
|
||||
Bottom i16
|
||||
left i16
|
||||
top i16
|
||||
right i16
|
||||
bottom i16
|
||||
}
|
||||
|
||||
struct ConsoleScreenBufferInfo {
|
||||
dwSize Coord
|
||||
dwCursorPosition Coord
|
||||
wAttributes u16
|
||||
srWindow SmallRect
|
||||
dwMaximumWindowSize Coord
|
||||
dw_size Coord
|
||||
dw_cursor_position Coord
|
||||
w_attributes u16
|
||||
sr_window SmallRect
|
||||
dw_maximum_window_size Coord
|
||||
}
|
||||
|
||||
fn C.GetConsoleScreenBufferInfo(handle os.HANDLE, info &ConsoleScreenBufferInfo) bool
|
||||
@ -28,13 +28,11 @@ fn C.GetConsoleScreenBufferInfo(handle os.HANDLE, info &ConsoleScreenBufferInfo)
|
||||
pub fn get_terminal_size() (int, int) {
|
||||
if is_atty(1) > 0 && os.getenv('TERM') != 'dumb' {
|
||||
info := ConsoleScreenBufferInfo{}
|
||||
|
||||
if C.GetConsoleScreenBufferInfo(C.GetStdHandle(C.STD_OUTPUT_HANDLE), &info) {
|
||||
columns := int(info.srWindow.Right - info.srWindow.Left + 1)
|
||||
rows := int(info.srWindow.Bottom - info.srWindow.Top + 1)
|
||||
columns := int(info.sr_window.right - info.sr_window.left + 1)
|
||||
rows := int(info.sr_window.bottom - info.sr_window.top + 1)
|
||||
return columns, rows
|
||||
}
|
||||
}
|
||||
|
||||
return default_columns_size, default_rows_size
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ pub:
|
||||
name string
|
||||
path string
|
||||
expr Expr
|
||||
pos token.Position
|
||||
is_skipped bool // module main can be skipped in single file programs
|
||||
}
|
||||
|
||||
@ -295,6 +296,7 @@ pub:
|
||||
name string
|
||||
expr Expr
|
||||
has_expr bool
|
||||
pos token.Position
|
||||
pub mut:
|
||||
typ table.Type
|
||||
}
|
||||
|
@ -175,15 +175,44 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
|
||||
return has_main_fn
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_valid_snake_case(name, identifier string, pos token.Position) {
|
||||
if name[0] == `_` {
|
||||
c.error('$identifier `$name` cannot start with `_`', pos)
|
||||
}
|
||||
if util.contains_capital(name) {
|
||||
c.error('$identifier `$name` cannot contain uppercase letters, use snake_case instead',
|
||||
pos)
|
||||
}
|
||||
}
|
||||
|
||||
fn stripped_name(name string) string {
|
||||
idx := name.last_index('.') or {
|
||||
-1
|
||||
}
|
||||
return name[(idx + 1)..]
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_valid_pascal_case(name, identifier string, pos token.Position) {
|
||||
stripped_name := stripped_name(name)
|
||||
if !stripped_name[0].is_capital() {
|
||||
c.error('$identifier `$name` must begin with capital letter', pos)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
||||
match node {
|
||||
ast.AliasTypeDecl {
|
||||
// TODO Replace `c.file.mod.name != 'time'` by `it.is_c` once available
|
||||
if c.file.mod.name != 'time' {
|
||||
c.check_valid_pascal_case(it.name, 'type alias', it.pos)
|
||||
}
|
||||
typ_sym := c.table.get_type_symbol(it.parent_type)
|
||||
if typ_sym.kind == .placeholder {
|
||||
c.error("type `$typ_sym.name` doesn't exist", it.pos)
|
||||
}
|
||||
}
|
||||
ast.FnTypeDecl {
|
||||
c.check_valid_pascal_case(it.name, 'fn type', it.pos)
|
||||
typ_sym := c.table.get_type_symbol(it.typ)
|
||||
fn_typ_info := typ_sym.info as table.FnType
|
||||
fn_info := fn_typ_info.func
|
||||
@ -199,6 +228,7 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
||||
}
|
||||
}
|
||||
ast.SumTypeDecl {
|
||||
c.check_valid_pascal_case(it.name, 'sum type', it.pos)
|
||||
for typ in it.sub_types {
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
if typ_sym.kind == .placeholder {
|
||||
@ -209,8 +239,21 @@ pub fn (mut c Checker) type_decl(node ast.TypeDecl) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) interface_decl(decl ast.InterfaceDecl) {
|
||||
c.check_valid_pascal_case(decl.name, 'interface name', decl.pos)
|
||||
for method in decl.methods {
|
||||
c.check_valid_snake_case(method.name, 'method name', method.pos)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) struct_decl(decl ast.StructDecl) {
|
||||
if !decl.is_c && !c.is_builtin_mod {
|
||||
c.check_valid_pascal_case(decl.name, 'struct name', decl.pos)
|
||||
}
|
||||
for i, field in decl.fields {
|
||||
if !decl.is_c {
|
||||
c.check_valid_snake_case(field.name, 'field name', field.pos)
|
||||
}
|
||||
for j in 0 .. i {
|
||||
if field.name == decl.fields[j].name {
|
||||
c.error('field name `$field.name` duplicate', field.pos)
|
||||
@ -1094,7 +1137,12 @@ pub fn (mut c Checker) return_stmt(mut return_stmt ast.Return) {
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) enum_decl(decl ast.EnumDecl) {
|
||||
c.check_valid_pascal_case(decl.name, 'enum name', decl.pos)
|
||||
for i, field in decl.fields {
|
||||
if util.contains_capital(field.name) {
|
||||
c.error('field name `$field.name` cannot contain uppercase letters, use snake_case instead',
|
||||
field.pos)
|
||||
}
|
||||
for j in 0 .. i {
|
||||
if field.name == decl.fields[j].name {
|
||||
c.error('field name `$field.name` duplicate', field.pos)
|
||||
@ -1165,13 +1213,8 @@ pub fn (mut c Checker) assign_stmt(mut assign_stmt ast.AssignStmt) {
|
||||
val_type := assign_stmt.right_types[i]
|
||||
// check variable name for beginning with capital letter 'Abc'
|
||||
is_decl := assign_stmt.op == .decl_assign
|
||||
if is_decl && util.contains_capital(ident.name) {
|
||||
c.error('variable names cannot contain uppercase letters, use snake_case instead',
|
||||
ident.pos)
|
||||
} else if is_decl && ident.kind != .blank_ident {
|
||||
if ident.name.starts_with('__') {
|
||||
c.error('variable names cannot start with `__`', ident.pos)
|
||||
}
|
||||
if is_decl && ident.name != '_' {
|
||||
c.check_valid_snake_case(ident.name, 'variable name', ident.pos)
|
||||
}
|
||||
if assign_stmt.op == .decl_assign {
|
||||
c.var_decl_name = ident.name
|
||||
@ -1385,6 +1428,7 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||
mut field_names := []string{}
|
||||
mut field_order := []int{}
|
||||
for i, field in it.fields {
|
||||
// TODO Check const name once the syntax is decided
|
||||
if field.name in c.const_names {
|
||||
c.error('field name `$field.name` duplicate', field.pos)
|
||||
}
|
||||
@ -1433,6 +1477,9 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||
c.check_expr_opt_call(it.expr, etype, false)
|
||||
}
|
||||
ast.FnDecl {
|
||||
if !it.is_c && !c.is_builtin_mod {
|
||||
c.check_valid_snake_case(it.name, 'function name', it.pos)
|
||||
}
|
||||
if it.is_method {
|
||||
sym := c.table.get_type_symbol(it.receiver.typ)
|
||||
if sym.kind == .interface_ {
|
||||
@ -1523,7 +1570,9 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||
c.stmts(it.stmts)
|
||||
c.in_for_count--
|
||||
}
|
||||
// ast.GlobalDecl {}
|
||||
ast.GlobalDecl {
|
||||
c.check_valid_snake_case(it.name, 'global name', it.pos)
|
||||
}
|
||||
ast.GoStmt {
|
||||
if !(it.call_expr is ast.CallExpr) {
|
||||
c.error('expression in `go` must be a function call', it.call_expr.position())
|
||||
@ -1533,19 +1582,12 @@ fn (mut c Checker) stmt(node ast.Stmt) {
|
||||
// ast.HashStmt {}
|
||||
ast.Import {}
|
||||
ast.InterfaceDecl {
|
||||
name := it.name.after('.')
|
||||
if !name[0].is_capital() {
|
||||
pos := token.Position{
|
||||
line_nr: it.pos.line_nr
|
||||
pos: it.pos.pos + 'interface'.len
|
||||
len: name.len
|
||||
}
|
||||
c.error('interface name must begin with capital letter', pos)
|
||||
}
|
||||
c.interface_decl(it)
|
||||
}
|
||||
ast.Module {
|
||||
c.mod = it.name
|
||||
c.is_builtin_mod = it.name == 'builtin'
|
||||
c.check_valid_snake_case(it.name, 'module name', it.pos)
|
||||
}
|
||||
ast.Return {
|
||||
c.returns = true
|
||||
@ -1865,7 +1907,7 @@ pub fn (mut c Checker) ident(mut ident ast.Ident) table.Type {
|
||||
return table.void_type
|
||||
}
|
||||
|
||||
pub fn (mut c Checker) concat_expr(concat_expr mut ast.ConcatExpr) table.Type {
|
||||
pub fn (mut c Checker) concat_expr(mut concat_expr ast.ConcatExpr) table.Type {
|
||||
mut mr_types := []table.Type{}
|
||||
for expr in concat_expr.vals {
|
||||
mr_types << c.expr(expr)
|
||||
|
@ -6,54 +6,59 @@ fn test_all() {
|
||||
vexe := os.getenv('VEXE')
|
||||
vroot := os.dir(vexe)
|
||||
os.chdir(vroot)
|
||||
dir := 'vlib/v/checker/tests'
|
||||
classic_dir := 'vlib/v/checker/tests'
|
||||
classic_tests := get_tests_in_dir(classic_dir)
|
||||
global_dir := '$classic_dir/globals'
|
||||
global_tests := get_tests_in_dir(global_dir)
|
||||
// -prod so that warns are errors
|
||||
total_errors += check_path(vexe, classic_dir, '-prod', '.out', classic_tests)
|
||||
total_errors += check_path(vexe, global_dir, '--enable-globals', '.out', global_tests)
|
||||
total_errors += check_path(vexe, classic_dir, '--enable-globals run', '.run.out', ['globals_error.vv'])
|
||||
assert total_errors == 0
|
||||
}
|
||||
|
||||
fn get_tests_in_dir(dir string) []string {
|
||||
files := os.ls(dir) or {
|
||||
panic(err)
|
||||
}
|
||||
mut tests := files.filter(it.ends_with('.vv'))
|
||||
if tests.len == 0 {
|
||||
println('no compiler tests found')
|
||||
assert false
|
||||
}
|
||||
tests.sort()
|
||||
for test in tests {
|
||||
// -prod so that warns are errors
|
||||
total_errors += check_path(vexe, dir, test, '-prod', '.out')
|
||||
}
|
||||
total_errors += check_path(vexe, dir, 'globals_error.vv', '--enable-globals run', '.run.out')
|
||||
assert total_errors == 0
|
||||
return tests
|
||||
}
|
||||
|
||||
fn check_path(vexe, dir, test, voptions, result_extension string) int {
|
||||
path := os.join_path(dir, test).replace('\\', '/')
|
||||
program := path.replace('.vv', '.v')
|
||||
print(program + ' ')
|
||||
os.cp(path, program) or {
|
||||
panic(err)
|
||||
fn check_path(vexe, dir, voptions, result_extension string, tests []string) int {
|
||||
mut nb_fail := 0
|
||||
for test in tests {
|
||||
path := os.join_path(dir, test).replace('\\', '/')
|
||||
program := path.replace('.vv', '.v')
|
||||
print(program + ' ')
|
||||
os.cp(path, program) or {
|
||||
panic(err)
|
||||
}
|
||||
res := os.exec('$vexe $voptions $program') or {
|
||||
panic(err)
|
||||
}
|
||||
mut expected := os.read_file(program.replace('.v', '') + result_extension) or {
|
||||
panic(err)
|
||||
}
|
||||
expected = clean_line_endings(expected)
|
||||
found := clean_line_endings(res.output)
|
||||
if expected != found {
|
||||
println(term.red('FAIL'))
|
||||
println('============')
|
||||
println('expected:')
|
||||
println(expected)
|
||||
println('============')
|
||||
println('found:')
|
||||
println(found)
|
||||
println('============\n')
|
||||
nb_fail += 1
|
||||
} else {
|
||||
println(term.green('OK'))
|
||||
os.rm(program)
|
||||
}
|
||||
}
|
||||
res := os.exec('$vexe $voptions $program') or {
|
||||
panic(err)
|
||||
}
|
||||
mut expected := os.read_file(program.replace('.v', '') + result_extension) or {
|
||||
panic(err)
|
||||
}
|
||||
expected = clean_line_endings(expected)
|
||||
found := clean_line_endings(res.output)
|
||||
if expected != found {
|
||||
println(term.red('FAIL'))
|
||||
println('============')
|
||||
println('expected:')
|
||||
println(expected)
|
||||
println('============')
|
||||
println('found:')
|
||||
println(found)
|
||||
println('============\n')
|
||||
return 1
|
||||
} else {
|
||||
println(term.green('OK'))
|
||||
os.rm(program)
|
||||
}
|
||||
return 0
|
||||
return nb_fail
|
||||
}
|
||||
|
||||
fn clean_line_endings(s string) string {
|
||||
|
@ -1,5 +0,0 @@
|
||||
vlib/v/checker/tests/decl_underscore.v:2:2: error: variable names cannot start with `__`
|
||||
1 | fn main() {
|
||||
2 | __abc := 1
|
||||
| ~~~~~
|
||||
3 | }
|
@ -1,3 +0,0 @@
|
||||
fn main() {
|
||||
__abc := 1
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
vlib/v/checker/tests/enum_field_name_err.v:2:5: error: field name `Green` must be all lowercase
|
||||
1 | enum Color {
|
||||
2 | Green
|
||||
| ~~~~~
|
||||
3 | yellow
|
||||
4 | }
|
@ -1,7 +0,0 @@
|
||||
enum Color {
|
||||
Green
|
||||
yellow
|
||||
}
|
||||
fn main(){
|
||||
println('hello')
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
vlib/v/checker/tests/enum_name_err.v:1:6: error: enum name `color` must begin with capital letter
|
||||
1 | enum color {
|
||||
| ~~~~~
|
||||
2 | green
|
||||
3 | yellow
|
3
vlib/v/checker/tests/globals/incorrect_name_global.out
Normal file
3
vlib/v/checker/tests/globals/incorrect_name_global.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/globals/incorrect_name_global.v:1:1: error: global name `A` cannot contain uppercase letters, use snake_case instead
|
||||
1 | __global A := 1
|
||||
| ~~~~~~~~~~
|
1
vlib/v/checker/tests/globals/incorrect_name_global.vv
Normal file
1
vlib/v/checker/tests/globals/incorrect_name_global.vv
Normal file
@ -0,0 +1 @@
|
||||
__global A := 1
|
3
vlib/v/checker/tests/incorrect_name_alias_type.out
Normal file
3
vlib/v/checker/tests/incorrect_name_alias_type.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_alias_type.v:1:1: error: type alias `integer` must begin with capital letter
|
||||
1 | type integer = int
|
||||
| ~~~~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_alias_type.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_alias_type.vv
Normal file
@ -0,0 +1 @@
|
||||
type integer = int
|
0
vlib/v/checker/tests/incorrect_name_const.out
Normal file
0
vlib/v/checker/tests/incorrect_name_const.out
Normal file
3
vlib/v/checker/tests/incorrect_name_const.vv
Normal file
3
vlib/v/checker/tests/incorrect_name_const.vv
Normal file
@ -0,0 +1,3 @@
|
||||
const (
|
||||
_my_const = 0
|
||||
)
|
5
vlib/v/checker/tests/incorrect_name_enum.out
Normal file
5
vlib/v/checker/tests/incorrect_name_enum.out
Normal file
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/incorrect_name_enum.v:1:1: error: enum name `color` must begin with capital letter
|
||||
1 | enum color {
|
||||
| ~~~~~~~~~~
|
||||
2 | green
|
||||
3 | yellow
|
@ -2,6 +2,3 @@ enum color {
|
||||
green
|
||||
yellow
|
||||
}
|
||||
fn main(){
|
||||
println('hello')
|
||||
}
|
6
vlib/v/checker/tests/incorrect_name_enum_field.out
Normal file
6
vlib/v/checker/tests/incorrect_name_enum_field.out
Normal file
@ -0,0 +1,6 @@
|
||||
vlib/v/checker/tests/incorrect_name_enum_field.v:2:5: error: field name `Green` cannot contain uppercase letters, use snake_case instead
|
||||
1 | enum Color {
|
||||
2 | Green
|
||||
| ~~~~~
|
||||
3 | red
|
||||
4 | blue
|
5
vlib/v/checker/tests/incorrect_name_enum_field.vv
Normal file
5
vlib/v/checker/tests/incorrect_name_enum_field.vv
Normal file
@ -0,0 +1,5 @@
|
||||
enum Color {
|
||||
Green
|
||||
red
|
||||
blue
|
||||
}
|
3
vlib/v/checker/tests/incorrect_name_fn_type.out
Normal file
3
vlib/v/checker/tests/incorrect_name_fn_type.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_fn_type.v:1:1: error: fn type `callback` must begin with capital letter
|
||||
1 | type callback = fn ()
|
||||
| ~~~~~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_fn_type.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_fn_type.vv
Normal file
@ -0,0 +1 @@
|
||||
type callback = fn ()
|
3
vlib/v/checker/tests/incorrect_name_function.out
Normal file
3
vlib/v/checker/tests/incorrect_name_function.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_function.v:1:1: error: function name `_my_fn` cannot start with `_`
|
||||
1 | fn _my_fn() {}
|
||||
| ~~~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_function.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_function.vv
Normal file
@ -0,0 +1 @@
|
||||
fn _my_fn() {}
|
3
vlib/v/checker/tests/incorrect_name_interface.out
Normal file
3
vlib/v/checker/tests/incorrect_name_interface.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_interface.v:1:1: error: interface name `_MyInterface` must begin with capital letter
|
||||
1 | interface _MyInterface {}
|
||||
| ~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_interface.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_interface.vv
Normal file
@ -0,0 +1 @@
|
||||
interface _MyInterface {}
|
5
vlib/v/checker/tests/incorrect_name_interface_method.out
Normal file
5
vlib/v/checker/tests/incorrect_name_interface_method.out
Normal file
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/incorrect_name_interface_method.v:2:5: error: method name `_speak` cannot start with `_`
|
||||
1 | interface MyInterface {
|
||||
2 | _speak()
|
||||
| ~~~~~~~~
|
||||
3 | }
|
3
vlib/v/checker/tests/incorrect_name_interface_method.vv
Normal file
3
vlib/v/checker/tests/incorrect_name_interface_method.vv
Normal file
@ -0,0 +1,3 @@
|
||||
interface MyInterface {
|
||||
_speak()
|
||||
}
|
3
vlib/v/checker/tests/incorrect_name_module.out
Normal file
3
vlib/v/checker/tests/incorrect_name_module.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_module.v:1:1: error: module name `_A` cannot start with `_`
|
||||
1 | module _A
|
||||
| ~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_module.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_module.vv
Normal file
@ -0,0 +1 @@
|
||||
module _A
|
3
vlib/v/checker/tests/incorrect_name_struct.out
Normal file
3
vlib/v/checker/tests/incorrect_name_struct.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_struct.v:1:8: error: struct name `abc` must begin with capital letter
|
||||
1 | struct abc {}
|
||||
| ~~~
|
1
vlib/v/checker/tests/incorrect_name_struct.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_struct.vv
Normal file
@ -0,0 +1 @@
|
||||
struct abc {}
|
5
vlib/v/checker/tests/incorrect_name_struct_field.out
Normal file
5
vlib/v/checker/tests/incorrect_name_struct_field.out
Normal file
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/incorrect_name_struct_field.v:2:5: error: field name `_a` cannot start with `_`
|
||||
1 | struct Abc {
|
||||
2 | _a int
|
||||
| ~~~~~~
|
||||
3 | }
|
3
vlib/v/checker/tests/incorrect_name_struct_field.vv
Normal file
3
vlib/v/checker/tests/incorrect_name_struct_field.vv
Normal file
@ -0,0 +1,3 @@
|
||||
struct Abc {
|
||||
_a int
|
||||
}
|
3
vlib/v/checker/tests/incorrect_name_sum_type.out
Normal file
3
vlib/v/checker/tests/incorrect_name_sum_type.out
Normal file
@ -0,0 +1,3 @@
|
||||
vlib/v/checker/tests/incorrect_name_sum_type.v:1:1: error: sum type `integer` must begin with capital letter
|
||||
1 | type integer = i8 | i16 | int | i64
|
||||
| ~~~~~~~~~~~~
|
1
vlib/v/checker/tests/incorrect_name_sum_type.vv
Normal file
1
vlib/v/checker/tests/incorrect_name_sum_type.vv
Normal file
@ -0,0 +1 @@
|
||||
type integer = i8 | i16 | int | i64
|
6
vlib/v/checker/tests/incorrect_name_variable.out
Normal file
6
vlib/v/checker/tests/incorrect_name_variable.out
Normal file
@ -0,0 +1,6 @@
|
||||
vlib/v/checker/tests/incorrect_name_variable.v:2:2: error: variable name `_abc` cannot start with `_`
|
||||
1 | fn main() {
|
||||
2 | _abc := 1
|
||||
| ~~~~
|
||||
3 | _ := _abc
|
||||
4 | }
|
4
vlib/v/checker/tests/incorrect_name_variable.vv
Normal file
4
vlib/v/checker/tests/incorrect_name_variable.vv
Normal file
@ -0,0 +1,4 @@
|
||||
fn main() {
|
||||
_abc := 1
|
||||
_ := _abc
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
vlib/v/checker/tests/struct_field_name_duplicate_err.v:3:4: error: field name `a` duplicate
|
||||
vlib/v/checker/tests/struct_field_name_duplicate_err.v:3:2: error: field name `a` duplicate
|
||||
1 | struct A {
|
||||
2 | a int
|
||||
3 | a string
|
||||
| ~~~~~~
|
||||
4 | }
|
||||
5 | fn main(){}
|
||||
| ~~~~~~~~
|
||||
4 | }
|
@ -2,4 +2,3 @@ struct A {
|
||||
a int
|
||||
a string
|
||||
}
|
||||
fn main(){}
|
||||
|
@ -1,5 +0,0 @@
|
||||
vlib/v/checker/tests/struct_name.v:1:8: error: struct name `abc` must begin with capital letter
|
||||
1 | struct abc {
|
||||
| ~~~
|
||||
2 |
|
||||
3 | }
|
@ -1,5 +0,0 @@
|
||||
struct abc {
|
||||
|
||||
}
|
||||
|
||||
fn main(){}
|
@ -468,7 +468,7 @@ pub fn (mut g Gen) writeln(s string) {
|
||||
|
||||
pub fn (mut g Gen) new_tmp_var() string {
|
||||
g.tmp_count++
|
||||
return 'tmp$g.tmp_count'
|
||||
return '_t$g.tmp_count'
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) reset_tmp_count() {
|
||||
@ -1860,7 +1860,6 @@ fn (mut g Gen) concat_expr(node ast.ConcatExpr) {
|
||||
styp := g.typ(node.return_type)
|
||||
sym := g.table.get_type_symbol(node.return_type)
|
||||
is_multi := sym.kind == .multi_return
|
||||
|
||||
if !is_multi {
|
||||
g.expr(node.vals[0])
|
||||
} else {
|
||||
|
@ -294,10 +294,9 @@ fn (mut p Parser) check_js_name() string {
|
||||
p.next() // .name
|
||||
p.next() // .dot
|
||||
}
|
||||
// last .name
|
||||
name += p.tok.lit
|
||||
// last .name
|
||||
name += p.tok.lit
|
||||
p.next()
|
||||
|
||||
return name
|
||||
}
|
||||
|
||||
@ -462,8 +461,8 @@ pub fn (mut p Parser) stmt() ast.Stmt {
|
||||
}
|
||||
} else if p.peek_tok.kind == .name {
|
||||
p.error_with_pos('unexpected name `$p.peek_tok.lit`', p.peek_tok.position())
|
||||
} else if !p.inside_if_expr && !p.inside_match_body &&
|
||||
!p.inside_or_expr && p.peek_tok.kind in [.rcbr, .eof] {
|
||||
} else if !p.inside_if_expr && !p.inside_match_body && !p.inside_or_expr && p.peek_tok.kind in
|
||||
[.rcbr, .eof] {
|
||||
p.error_with_pos('`$p.tok.lit` evaluated but not used', p.tok.position())
|
||||
}
|
||||
epos := p.tok.position()
|
||||
@ -528,7 +527,8 @@ pub fn (mut p Parser) stmt() ast.Stmt {
|
||||
}
|
||||
}
|
||||
.key_const {
|
||||
p.error_with_pos('const can only be defined at the top level (outside of functions)', p.tok.position())
|
||||
p.error_with_pos('const can only be defined at the top level (outside of functions)',
|
||||
p.tok.position())
|
||||
}
|
||||
else {
|
||||
return p.parse_comma_separated()
|
||||
@ -680,7 +680,7 @@ fn (mut p Parser) parse_comma_separated() ast.Stmt {
|
||||
}
|
||||
}
|
||||
return ast.ExprStmt{
|
||||
expr: ast.ConcatExpr {
|
||||
expr: ast.ConcatExpr{
|
||||
vals: collected
|
||||
}
|
||||
pos: p.tok.position()
|
||||
@ -706,7 +706,7 @@ pub fn (mut p Parser) parse_ident(is_c, is_js bool) ast.Ident {
|
||||
name: '_'
|
||||
kind: .blank_ident
|
||||
pos: pos
|
||||
info: ast.IdentVar {
|
||||
info: ast.IdentVar{
|
||||
is_mut: false
|
||||
is_static: false
|
||||
}
|
||||
@ -862,7 +862,7 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||
} else if p.peek_tok.kind == .colon && p.prev_tok.kind != .str_dollar {
|
||||
// `foo(key:val, key2:val2)`
|
||||
return p.struct_init(true) // short_syntax:true
|
||||
// JS. function call with more than 1 dot
|
||||
// JS. function call with more than 1 dot
|
||||
} else if is_js && p.peek_tok.kind == .dot && p.peek_tok2.kind == .name {
|
||||
node = p.call_expr(is_c, is_js, mod)
|
||||
} else {
|
||||
@ -1105,8 +1105,9 @@ fn (mut p Parser) parse_number_literal() ast.Expr {
|
||||
fn (mut p Parser) module_decl() ast.Module {
|
||||
mut name := 'main'
|
||||
is_skipped := p.tok.kind != .key_module
|
||||
mut module_pos := token.Position{}
|
||||
if !is_skipped {
|
||||
module_pos := p.tok.position()
|
||||
module_pos = p.tok.position()
|
||||
p.next()
|
||||
mut pos := p.tok.position()
|
||||
name = p.check_name()
|
||||
@ -1121,6 +1122,7 @@ fn (mut p Parser) module_decl() ast.Module {
|
||||
p.error_with_pos('`module x` can only declare one module', pos)
|
||||
}
|
||||
}
|
||||
module_pos = module_pos.extend(pos)
|
||||
}
|
||||
full_mod := p.table.qualify_module(name, p.file_name)
|
||||
p.mod = full_mod
|
||||
@ -1128,6 +1130,7 @@ fn (mut p Parser) module_decl() ast.Module {
|
||||
return ast.Module{
|
||||
name: full_mod
|
||||
is_skipped: is_skipped
|
||||
pos: module_pos
|
||||
}
|
||||
}
|
||||
|
||||
@ -1252,7 +1255,9 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
|
||||
p.mod != 'ui' && p.mod != 'gg2' && p.mod != 'uiold' && !os.getwd().contains('/volt') && !p.pref.enable_globals {
|
||||
p.error('use `v --enable-globals ...` to enable globals')
|
||||
}
|
||||
start_pos := p.tok.position()
|
||||
p.next()
|
||||
pos := start_pos.extend(p.tok.position())
|
||||
name := p.check_name()
|
||||
// println(name)
|
||||
typ := p.parse_type()
|
||||
@ -1280,6 +1285,7 @@ fn (mut p Parser) global_decl() ast.GlobalDecl {
|
||||
glob := ast.GlobalDecl{
|
||||
name: name
|
||||
typ: typ
|
||||
pos: pos
|
||||
has_expr: has_expr
|
||||
expr: expr
|
||||
}
|
||||
@ -1296,9 +1302,6 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
||||
p.check(.key_enum)
|
||||
end_pos := p.tok.position()
|
||||
enum_name := p.check_name()
|
||||
if enum_name.len > 0 && !enum_name[0].is_capital() {
|
||||
p.error_with_pos('enum name `$enum_name` must begin with capital letter', end_pos)
|
||||
}
|
||||
name := p.prepend_mod(enum_name)
|
||||
p.check(.lcbr)
|
||||
mut vals := []string{}
|
||||
@ -1307,9 +1310,6 @@ fn (mut p Parser) enum_decl() ast.EnumDecl {
|
||||
for p.tok.kind != .eof && p.tok.kind != .rcbr {
|
||||
pos := p.tok.position()
|
||||
val := p.check_name()
|
||||
if !val.is_lower() {
|
||||
p.error_with_pos('field name `$val` must be all lowercase', pos)
|
||||
}
|
||||
vals << val
|
||||
mut expr := ast.Expr{}
|
||||
mut has_expr := false
|
||||
|
@ -95,8 +95,9 @@ fn (mut p Parser) struct_decl() ast.StructDecl {
|
||||
is_field_mut = true
|
||||
is_field_global = true
|
||||
}
|
||||
field_start_pos := p.tok.position()
|
||||
field_name := p.check_name()
|
||||
field_pos := p.tok.position()
|
||||
field_pos := field_start_pos.extend(p.tok.position())
|
||||
// p.warn('field $field_name')
|
||||
typ := p.parse_type()
|
||||
/*
|
||||
@ -288,6 +289,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
||||
// Parse methods
|
||||
mut methods := []ast.FnDecl{}
|
||||
for p.tok.kind != .rcbr && p.tok.kind != .eof {
|
||||
method_start_pos := p.tok.position()
|
||||
line_nr := p.tok.line_nr
|
||||
name := p.check_name()
|
||||
if util.contains_capital(name) {
|
||||
@ -307,6 +309,7 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl {
|
||||
file: p.file_name
|
||||
return_type: table.void_type
|
||||
is_pub: true
|
||||
pos: method_start_pos.extend(p.prev_tok.position())
|
||||
}
|
||||
if p.tok.kind.is_start_of_type() && p.tok.line_nr == line_nr {
|
||||
method.return_type = p.parse_type()
|
||||
|
@ -1,15 +1,11 @@
|
||||
// 1 line comment
|
||||
|
||||
/* 1 line comment */
|
||||
|
||||
// 1 line comment // 1 line comment
|
||||
/*
|
||||
multi line comment (1)
|
||||
multi line comment (2)
|
||||
multi line comment (3)
|
||||
*/
|
||||
|
||||
/*
|
||||
multi line comment (1)
|
||||
multi line comment (1)
|
||||
/*
|
||||
nested comment
|
||||
*/
|
||||
@ -20,44 +16,43 @@ multi line comment (3)
|
||||
/* /* nested comment */ */
|
||||
multi line comment (2)
|
||||
*/
|
||||
type MyFn1 = fn (int) string
|
||||
|
||||
type myfn fn (int) string
|
||||
type MyFn2 = fn (a int, b int) int
|
||||
|
||||
type myfn2 fn (a int, b int) int
|
||||
|
||||
type myfn3 fn (int, int)
|
||||
type MyFn3 = fn (int, int)
|
||||
|
||||
fn myfn4(string)
|
||||
|
||||
fn foobar()
|
||||
|
||||
fn slopediv(num u32, den u32) int
|
||||
fn slopediv(num, den u32) int
|
||||
|
||||
type f1 fn ()
|
||||
type F1 = fn ()
|
||||
|
||||
type f2 fn (voidptr)
|
||||
type F2 = fn (voidptr)
|
||||
|
||||
type f3 fn (voidptr, voidptr)
|
||||
type F3 = fn (voidptr, voidptr)
|
||||
|
||||
type f4 fn (voidptr) int
|
||||
type F4 = fn (voidptr) int
|
||||
|
||||
type f5 fn (int, int) int
|
||||
type F5 = fn (int, int) int
|
||||
|
||||
type f6 fn (int, int)
|
||||
type F6 = fn (int, int)
|
||||
|
||||
fn C.atoi(byteptr) int
|
||||
|
||||
fn foo() {
|
||||
}
|
||||
|
||||
type actionf_v fn ()
|
||||
type ActionfV = fn ()
|
||||
|
||||
type actionf_p1 fn (voidptr)
|
||||
type ActionfP1 = fn (voidptr)
|
||||
|
||||
type actionf_p2 fn (voidptr, voidptr)
|
||||
type ActionfP2 = fn (voidptr, voidptr)
|
||||
|
||||
// TODO
|
||||
fn modify_array(a mut []int) {
|
||||
fn modify_array(mut a []int) {
|
||||
a[0] = 10
|
||||
for i in 0 .. a.len {
|
||||
a[i] = a[i] * 2
|
||||
@ -86,7 +81,7 @@ fn test_mut_array() {
|
||||
println(nums.clone())
|
||||
}
|
||||
|
||||
fn mod_struct(user mut User) {
|
||||
fn mod_struct(mut user User) {
|
||||
user.age++
|
||||
}
|
||||
|
||||
@ -101,7 +96,7 @@ fn test_mut_struct() {
|
||||
assert user.age == 19
|
||||
}
|
||||
|
||||
fn mod_ptr(buf mut byteptr) {
|
||||
fn mod_ptr(mut buf byteptr) {
|
||||
buf[0] = 77
|
||||
}
|
||||
|
||||
@ -111,7 +106,6 @@ fn test_mut_ptr() {
|
||||
assert buf[0] == 77
|
||||
}
|
||||
|
||||
|
||||
fn assert_in_bool_fn(v int) bool {
|
||||
assert v < 3
|
||||
return true
|
||||
@ -121,7 +115,8 @@ fn test_assert_in_bool_fn() {
|
||||
assert_in_bool_fn(2)
|
||||
}
|
||||
|
||||
type MyFn fn (int) int
|
||||
type MyFn = fn (int) int
|
||||
|
||||
fn test(n int) int {
|
||||
return n + 1000
|
||||
}
|
||||
@ -129,18 +124,21 @@ fn test(n int) int {
|
||||
struct MySt {
|
||||
f MyFn
|
||||
}
|
||||
|
||||
fn test_fn_type_call() {
|
||||
mut arr := []MyFn{}
|
||||
arr << MyFn(test)
|
||||
mut arr := []MyFn{}
|
||||
arr << MyFn(test)
|
||||
// TODO: `arr[0](10)`
|
||||
// assert arr[0](10) == 1010
|
||||
x1 := arr[0]
|
||||
x2 := x1(10)
|
||||
assert x2 == 1010
|
||||
|
||||
st := MySt{f:test}
|
||||
assert st.f(10) == 1010
|
||||
|
||||
st1 := &MySt{f:test}
|
||||
assert st1.f(10) == 1010
|
||||
st := MySt{
|
||||
f: test
|
||||
}
|
||||
assert st.f(10) == 1010
|
||||
st1 := &MySt{
|
||||
f: test
|
||||
}
|
||||
assert st1.f(10) == 1010
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user