mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
parent
bbd0603b41
commit
46921480fc
@ -712,10 +712,10 @@ pub mut:
|
||||
[minify]
|
||||
pub struct EmbeddedFile {
|
||||
pub:
|
||||
rpath string // used in the source code, as an ID/key to the embed
|
||||
apath string // absolute path during compilation to the resource
|
||||
compression_type string
|
||||
pub mut:
|
||||
rpath string // used in the source code, as an ID/key to the embed
|
||||
apath string // absolute path during compilation to the resource
|
||||
// these are set by gen_embed_file_init in v/gen/c/embed
|
||||
is_compressed bool
|
||||
bytes []u8
|
||||
@ -1683,7 +1683,6 @@ pub:
|
||||
method_pos token.Pos
|
||||
scope &Scope = unsafe { nil }
|
||||
left Expr
|
||||
args_var string
|
||||
//
|
||||
is_vweb bool
|
||||
vweb_tmpl File
|
||||
@ -1698,6 +1697,7 @@ pub mut:
|
||||
left_type Type
|
||||
result_type Type
|
||||
env_value string
|
||||
args_var string
|
||||
args []CallArg
|
||||
embed_file EmbeddedFile
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Use of this source code is governed by an MIT license that can be found in the LICENSE file.
|
||||
module checker
|
||||
|
||||
import os
|
||||
import v.ast
|
||||
import v.pref
|
||||
import v.token
|
||||
@ -29,6 +30,46 @@ fn (mut c Checker) comptime_call(mut node ast.ComptimeCall) ast.Type {
|
||||
return ast.string_type
|
||||
}
|
||||
if node.is_embed {
|
||||
if node.args.len == 1 {
|
||||
embed_arg := node.args[0]
|
||||
mut raw_path := ''
|
||||
if embed_arg.expr is ast.StringLiteral {
|
||||
raw_path = embed_arg.expr.val
|
||||
} else if embed_arg.expr is ast.Ident {
|
||||
if var := c.fn_scope.find_var(embed_arg.expr.name) {
|
||||
if var.expr is ast.StringLiteral {
|
||||
raw_path = var.expr.val
|
||||
}
|
||||
}
|
||||
}
|
||||
mut escaped_path := raw_path.replace('/', os.path_separator)
|
||||
// Validate that the epath exists, and that it is actually a file.
|
||||
if escaped_path == '' {
|
||||
c.error('supply a valid relative or absolute file path to the file to embed, that is known at compile time',
|
||||
node.pos)
|
||||
return ast.string_type
|
||||
}
|
||||
abs_path := os.real_path(escaped_path)
|
||||
// check absolute path first
|
||||
if !os.exists(abs_path) {
|
||||
// ... look relative to the source file:
|
||||
escaped_path = os.real_path(os.join_path_single(os.dir(c.file.path), escaped_path))
|
||||
if !os.exists(escaped_path) {
|
||||
c.error('"$escaped_path" does not exist so it cannot be embedded',
|
||||
node.pos)
|
||||
return ast.string_type
|
||||
}
|
||||
if !os.is_file(escaped_path) {
|
||||
c.error('"$escaped_path" is not a file so it cannot be embedded',
|
||||
node.pos)
|
||||
return ast.string_type
|
||||
}
|
||||
} else {
|
||||
escaped_path = abs_path
|
||||
}
|
||||
node.embed_file.rpath = raw_path
|
||||
node.embed_file.apath = escaped_path
|
||||
}
|
||||
// c.file.embedded_files << node.embed_file
|
||||
if node.embed_file.compression_type !in constants.valid_comptime_compression_types {
|
||||
supported := constants.valid_comptime_compression_types.map('.$it').join(', ')
|
||||
|
@ -0,0 +1,6 @@
|
||||
fn test_embed_file_with_variable_arg() {
|
||||
path := './a.txt'
|
||||
s := $embed_file(path).to_string()
|
||||
println(s)
|
||||
assert s.trim_space() == 'test'
|
||||
}
|
@ -1882,9 +1882,9 @@ pub fn (mut f Fmt) comptime_call(node ast.ComptimeCall) {
|
||||
} else {
|
||||
if node.is_embed {
|
||||
if node.embed_file.compression_type == 'none' {
|
||||
f.write("\$embed_file('$node.embed_file.rpath')")
|
||||
f.write('\$embed_file(${node.args[0].expr})')
|
||||
} else {
|
||||
f.write("\$embed_file('$node.embed_file.rpath', .$node.embed_file.compression_type)")
|
||||
f.write('\$embed_file(${node.args[0].expr}, .$node.embed_file.compression_type)')
|
||||
}
|
||||
} else if node.is_env {
|
||||
f.write("\$env('$node.args_var')")
|
||||
|
@ -123,8 +123,12 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
|
||||
}
|
||||
literal_string_param := if is_html { '' } else { p.tok.lit }
|
||||
path_of_literal_string_param := literal_string_param.replace('/', os.path_separator)
|
||||
mut arg := ast.CallArg{}
|
||||
if !is_html {
|
||||
p.check(.string)
|
||||
arg_expr := p.expr(0)
|
||||
arg = ast.CallArg{
|
||||
expr: arg_expr
|
||||
}
|
||||
}
|
||||
mut embed_compression_type := 'none'
|
||||
if is_embed_file {
|
||||
@ -137,33 +141,6 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
|
||||
p.check(.rpar)
|
||||
// $embed_file('/path/to/file')
|
||||
if is_embed_file {
|
||||
mut epath := path_of_literal_string_param
|
||||
// Validate that the epath exists, and that it is actually a file.
|
||||
if epath == '' {
|
||||
p.error_with_pos('supply a valid relative or absolute file path to the file to embed',
|
||||
start_pos)
|
||||
return err_node
|
||||
}
|
||||
if !p.pref.is_fmt {
|
||||
abs_path := os.real_path(epath)
|
||||
// check absolute path first
|
||||
if !os.exists(abs_path) {
|
||||
// ... look relative to the source file:
|
||||
epath = os.real_path(os.join_path_single(os.dir(p.file_name), epath))
|
||||
if !os.exists(epath) {
|
||||
p.error_with_pos('"$epath" does not exist so it cannot be embedded',
|
||||
start_pos)
|
||||
return err_node
|
||||
}
|
||||
if !os.is_file(epath) {
|
||||
p.error_with_pos('"$epath" is not a file so it cannot be embedded',
|
||||
start_pos)
|
||||
return err_node
|
||||
}
|
||||
} else {
|
||||
epath = abs_path
|
||||
}
|
||||
}
|
||||
p.register_auto_import('v.preludes.embed_file')
|
||||
if embed_compression_type == 'zlib' {
|
||||
p.register_auto_import('v.preludes.embed_file.zlib')
|
||||
@ -172,10 +149,9 @@ fn (mut p Parser) comptime_call() ast.ComptimeCall {
|
||||
scope: 0
|
||||
is_embed: true
|
||||
embed_file: ast.EmbeddedFile{
|
||||
rpath: literal_string_param
|
||||
apath: epath
|
||||
compression_type: embed_compression_type
|
||||
}
|
||||
args: [arg]
|
||||
pos: start_pos.extend(p.prev_tok.pos())
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user