checker: deprecate using V strings in C function calls (#10140)

pull/10147/head
Enzo 2021-05-20 08:17:44 +02:00 committed by GitHub
parent b0de1f76e8
commit 906b207e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 27 additions and 25 deletions

View File

@ -3506,7 +3506,7 @@ fn my_callback(arg voidptr, howmany int, cvalues &&char, cnames &&char) int {
fn main() { fn main() {
db := &C.sqlite3(0) // this means `sqlite3* db = 0` db := &C.sqlite3(0) // this means `sqlite3* db = 0`
// passing a string literal to a C function call results in a C string, not a V string // passing a string literal to a C function call results in a C string, not a V string
C.sqlite3_open('users.db', &db) C.sqlite3_open(c'users.db', &db)
// C.sqlite3_open(db_path.str, &db) // C.sqlite3_open(db_path.str, &db)
query := 'select count(*) from users' query := 'select count(*) from users'
stmt := &C.sqlite3_stmt(0) stmt := &C.sqlite3_stmt(0)

View File

@ -62,7 +62,7 @@ fn main() {
converter := C.wkhtmltopdf_create_converter(global_settings) converter := C.wkhtmltopdf_create_converter(global_settings)
println('wkhtmltopdf_create_converter: ${voidptr(converter)}') println('wkhtmltopdf_create_converter: ${voidptr(converter)}')
// convert // convert
mut result := C.wkhtmltopdf_set_object_setting(object_settings, 'page', 'http://www.google.com.br') mut result := C.wkhtmltopdf_set_object_setting(object_settings, c'page', c'http://www.google.com.br')
println('wkhtmltopdf_set_object_setting: $result [page = http://www.google.com.br]') println('wkhtmltopdf_set_object_setting: $result [page = http://www.google.com.br]')
C.wkhtmltopdf_add_object(converter, object_settings, 0) C.wkhtmltopdf_add_object(converter, object_settings, 0)
println('wkhtmltopdf_add_object') println('wkhtmltopdf_add_object')

View File

@ -48,7 +48,7 @@ fn init(mut state AppState) {
// or use DroidSerif-Regular.ttf // or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) { if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len') println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, state.font_normal = C.fonsAddFontMem(state.fons, c'sans', bytes.data, bytes.len,
false) false)
} }
} }

View File

@ -101,7 +101,7 @@ fn init(user_data voidptr) {
// or use DroidSerif-Regular.ttf // or use DroidSerif-Regular.ttf
if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) { if bytes := os.read_bytes(os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf')) {
println('loaded font: $bytes.len') println('loaded font: $bytes.len')
state.font_normal = C.fonsAddFontMem(state.fons, 'sans', bytes.data, bytes.len, state.font_normal = C.fonsAddFontMem(state.fons, c'sans', bytes.data, bytes.len,
false) false)
} }
} }

View File

@ -68,13 +68,13 @@ fn new_ft(c FTConfig) ?&FT {
return &FT{ return &FT{
fons: fons fons: fons
font_normal: C.fonsAddFontMem(fons, 'sans', bytes_normal.data, bytes_normal.len, font_normal: C.fonsAddFontMem(fons, c'sans', bytes_normal.data, bytes_normal.len,
false) false)
font_bold: C.fonsAddFontMem(fons, 'sans', bytes_bold.data, bytes_bold.len, font_bold: C.fonsAddFontMem(fons, c'sans', bytes_bold.data, bytes_bold.len,
false) false)
font_mono: C.fonsAddFontMem(fons, 'sans', bytes_mono.data, bytes_mono.len, font_mono: C.fonsAddFontMem(fons, c'sans', bytes_mono.data, bytes_mono.len,
false) false)
font_italic: C.fonsAddFontMem(fons, 'sans', bytes_italic.data, bytes_italic.len, font_italic: C.fonsAddFontMem(fons, c'sans', bytes_italic.data, bytes_italic.len,
false) false)
scale: c.scale scale: c.scale
} }
@ -129,10 +129,10 @@ fn new_ft(c FTConfig) ?&FT {
fons := sfons.create(512, 512, 1) fons := sfons.create(512, 512, 1)
return &FT{ return &FT{
fons: fons fons: fons
font_normal: C.fonsAddFontMem(fons, 'sans', bytes.data, bytes.len, false) font_normal: C.fonsAddFontMem(fons, c'sans', bytes.data, bytes.len, false)
font_bold: C.fonsAddFontMem(fons, 'sans', bytes_bold.data, bytes_bold.len, false) font_bold: C.fonsAddFontMem(fons, c'sans', bytes_bold.data, bytes_bold.len, false)
font_mono: C.fonsAddFontMem(fons, 'sans', bytes_mono.data, bytes_mono.len, false) font_mono: C.fonsAddFontMem(fons, c'sans', bytes_mono.data, bytes_mono.len, false)
font_italic: C.fonsAddFontMem(fons, 'sans', bytes_italic.data, bytes_italic.len, font_italic: C.fonsAddFontMem(fons, c'sans', bytes_italic.data, bytes_italic.len,
false) false)
scale: c.scale scale: c.scale
} }

View File

@ -116,7 +116,7 @@ fn (a Vec3) print() {
x := a.x x := a.x
y := a.y y := a.y
z := a.z z := a.z
C.printf('vec3{%f,%f,%f}\n', x, y, z) C.printf(c'vec3{%f,%f,%f}\n', x, y, z)
// println('vec3{$x,$y,$z}') // println('vec3{$x,$y,$z}')
} }

View File

@ -16,7 +16,7 @@ fn (req &Request) ssl_do(port int, method Method, host_name string, path string)
C.SSL_CTX_set_verify_depth(ctx, 4) C.SSL_CTX_set_verify_depth(ctx, 4)
flags := C.SSL_OP_NO_SSLv2 | C.SSL_OP_NO_SSLv3 | C.SSL_OP_NO_COMPRESSION flags := C.SSL_OP_NO_SSLv2 | C.SSL_OP_NO_SSLv3 | C.SSL_OP_NO_COMPRESSION
C.SSL_CTX_set_options(ctx, flags) C.SSL_CTX_set_options(ctx, flags)
mut res := C.SSL_CTX_load_verify_locations(ctx, 'random-org-chain.pem', 0) mut res := C.SSL_CTX_load_verify_locations(ctx, c'random-org-chain.pem', 0)
web := C.BIO_new_ssl_connect(ctx) web := C.BIO_new_ssl_connect(ctx)
addr := host_name + ':' + port.str() addr := host_name + ':' + port.str()
res = C.BIO_set_conn_hostname(web, addr.str) res = C.BIO_set_conn_hostname(web, addr.str)

View File

@ -89,6 +89,7 @@ mut:
inside_println_arg bool inside_println_arg bool
inside_decl_rhs bool inside_decl_rhs bool
need_recheck_generic_fns bool // need recheck generic fns because there are cascaded nested generic fn need_recheck_generic_fns bool // need recheck generic fns because there are cascaded nested generic fn
is_c_call bool // remove once C.c_call("string") deprecation is removed
} }
pub fn new_checker(table &ast.Table, pref &pref.Preferences) Checker { pub fn new_checker(table &ast.Table, pref &pref.Preferences) Checker {
@ -2165,6 +2166,11 @@ fn (mut c Checker) array_builtin_method_call(mut call_expr ast.CallExpr, left_ty
} }
pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type { pub fn (mut c Checker) fn_call(mut call_expr ast.CallExpr) ast.Type {
was_c_call := c.is_c_call
c.is_c_call = call_expr.language == .c
defer {
c.is_c_call = was_c_call
}
fn_name := call_expr.name fn_name := call_expr.name
if fn_name == 'main' { if fn_name == 'main' {
c.error('the `main` function cannot be called in the program', call_expr.pos) c.error('the `main` function cannot be called in the program', call_expr.pos)
@ -4737,6 +4743,10 @@ pub fn (mut c Checker) expr(node ast.Expr) ast.Type {
// string literal starts with "c": `C.printf(c'hello')` // string literal starts with "c": `C.printf(c'hello')`
return ast.byte_type.set_nr_muls(1) return ast.byte_type.set_nr_muls(1)
} }
if node.language != .c && c.is_c_call {
c.warn("automatic string to C-string conversion is deprecated and will be removed on 2021-06-19, use `c'<string_value>'` and set the C function parameter type to `&u8`",
node.pos)
}
return ast.string_type return ast.string_type
} }
ast.StringInterLiteral { ast.StringInterLiteral {

View File

@ -829,8 +829,8 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
} }
if node.language == .c { if node.language == .c {
// Skip "C." // Skip "C."
g.is_c_call = true
name = util.no_dots(name[2..]) name = util.no_dots(name[2..])
g.is_c_call = true
} else { } else {
name = c_name(name) name = c_name(name)
} }

View File

@ -21,12 +21,6 @@ fn (mut g Gen) string_literal(node ast.StringLiteral) {
// `C.printf("hi")` => `printf("hi");` // `C.printf("hi")` => `printf("hi");`
g.write('"$escaped_val"') g.write('"$escaped_val"')
} else { } else {
// TODO calculate the literal's length in V, it's a bit tricky with all the
// escape characters.
// Clang and GCC optimize `strlen("lorem ipsum")` to `11`
// g.write('tos4("$escaped_val", strlen("$escaped_val"))')
// g.write('tos4("$escaped_val", $it.val.len)')
// g.write('_SLIT("$escaped_val")')
g.write('_SLIT("$escaped_val")') g.write('_SLIT("$escaped_val")')
} }
} }

View File

@ -1,10 +1,8 @@
fn test_cstring() { fn test_cstring() {
w := &char(c'world') w := &char(c'world')
hlen := unsafe { C.strlen(c'hello') } hlen := unsafe { C.strlen(c'hello') }
hlen2 := unsafe { C.strlen('hello') }
wlen := unsafe { C.strlen(w) } wlen := unsafe { C.strlen(w) }
assert hlen == 5 assert hlen == 5
assert hlen2 == 5
assert wlen == 5 assert wlen == 5
} }

View File

@ -12,7 +12,7 @@ pub fn smart_quote(str string, raw bool) string {
if len == 0 { if len == 0 {
return str return str
} }
mut result := strings.new_builder(0) mut result := strings.new_builder(len)
mut pos := -1 mut pos := -1
mut last := '' mut last := ''
// TODO: This should be a single char? // TODO: This should be a single char?