mirror of
https://github.com/vlang/v.git
synced 2025-09-15 15:32:27 +03:00
fmt: fix alignment of struct init fields (#22025)
This commit is contained in:
parent
99da5726db
commit
c51d30bf53
671 changed files with 18817 additions and 18787 deletions
|
@ -133,7 +133,7 @@ fn new_gen_vc(flag_options FlagOptions) &GenVC {
|
|||
}
|
||||
return &GenVC{
|
||||
options: flag_options
|
||||
logger: logger
|
||||
logger: logger
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -171,14 +171,14 @@ pub fn (ws &WebhookServer) reset() {
|
|||
// parse flags to FlagOptions struct
|
||||
fn parse_flags(mut fp flag.FlagParser) FlagOptions {
|
||||
return FlagOptions{
|
||||
serve: fp.bool('serve', 0, false, 'run in webhook server mode')
|
||||
serve: fp.bool('serve', 0, false, 'run in webhook server mode')
|
||||
work_dir: fp.string('work-dir', 0, work_dir, 'gen_vc working directory')
|
||||
purge: fp.bool('purge', 0, false, 'force purge the local repositories')
|
||||
port: fp.int('port', 0, server_port, 'port for web server to listen on')
|
||||
log_to: fp.string('log-to', 0, log_to, "log to is 'file' or 'terminal'")
|
||||
purge: fp.bool('purge', 0, false, 'force purge the local repositories')
|
||||
port: fp.int('port', 0, server_port, 'port for web server to listen on')
|
||||
log_to: fp.string('log-to', 0, log_to, "log to is 'file' or 'terminal'")
|
||||
log_file: fp.string('log-file', 0, log_file, "log file to use when log-to is 'file'")
|
||||
dry_run: fp.bool('dry-run', 0, dry_run, 'when specified dont push anything to remote repo')
|
||||
force: fp.bool('force', 0, false, 'force update even if already up to date')
|
||||
dry_run: fp.bool('dry-run', 0, dry_run, 'when specified dont push anything to remote repo')
|
||||
force: fp.bool('force', 0, false, 'force update even if already up to date')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,13 +84,13 @@ fn process_files(files []string) ! {
|
|||
fn new_parser(path string, comments_mode scanner.CommentsMode, table &ast.Table, pref_ &pref.Preferences) &parser.Parser {
|
||||
mut p := &parser.Parser{
|
||||
scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
|
||||
table: table
|
||||
pref: pref_
|
||||
scope: &ast.Scope{
|
||||
table: table
|
||||
pref: pref_
|
||||
scope: &ast.Scope{
|
||||
start_pos: 0
|
||||
parent: table.global_scope
|
||||
parent: table.global_scope
|
||||
}
|
||||
errors: []errors.Error{}
|
||||
errors: []errors.Error{}
|
||||
warnings: []errors.Warning{}
|
||||
}
|
||||
p.set_path(path)
|
||||
|
|
|
@ -79,13 +79,13 @@ fn process_files(files []string) ! {
|
|||
fn new_parser(path string, comments_mode scanner.CommentsMode, table &ast.Table, pref_ &pref.Preferences) &parser.Parser {
|
||||
mut p := &parser.Parser{
|
||||
scanner: scanner.new_scanner_file(path, comments_mode, pref_) or { panic(err) }
|
||||
table: table
|
||||
pref: pref_
|
||||
scope: &ast.Scope{
|
||||
table: table
|
||||
pref: pref_
|
||||
scope: &ast.Scope{
|
||||
start_pos: 0
|
||||
parent: table.global_scope
|
||||
parent: table.global_scope
|
||||
}
|
||||
errors: []errors.Error{}
|
||||
errors: []errors.Error{}
|
||||
warnings: []errors.Warning{}
|
||||
}
|
||||
p.set_path(path)
|
||||
|
|
|
@ -117,22 +117,22 @@ mut:
|
|||
|
||||
fn (mut ts TestSession) append_message(kind MessageKind, msg string, mtc MessageThreadContext) {
|
||||
ts.nmessages <- LogMessage{
|
||||
file: mtc.file
|
||||
file: mtc.file
|
||||
flow_id: mtc.flow_id
|
||||
message: msg
|
||||
kind: kind
|
||||
when: time.now()
|
||||
kind: kind
|
||||
when: time.now()
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut ts TestSession) append_message_with_duration(kind MessageKind, msg string, d time.Duration, mtc MessageThreadContext) {
|
||||
ts.nmessages <- LogMessage{
|
||||
file: mtc.file
|
||||
file: mtc.file
|
||||
flow_id: mtc.flow_id
|
||||
message: msg
|
||||
kind: kind
|
||||
when: time.now()
|
||||
took: d
|
||||
kind: kind
|
||||
when: time.now()
|
||||
took: d
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -310,16 +310,16 @@ pub fn new_test_session(_vargs string, will_compile bool) TestSession {
|
|||
os.setenv('VCOLORS', 'always', true)
|
||||
}
|
||||
mut ts := TestSession{
|
||||
vexe: vexe
|
||||
vroot: vroot
|
||||
skip_files: skip_files
|
||||
fail_fast: testing.fail_fast
|
||||
show_stats: '-stats' in vargs.split(' ')
|
||||
show_asserts: '-show-asserts' in vargs.split(' ')
|
||||
vargs: vargs
|
||||
vtmp_dir: new_vtmp_dir
|
||||
hash: hash
|
||||
silent_mode: _vargs.contains('-silent')
|
||||
vexe: vexe
|
||||
vroot: vroot
|
||||
skip_files: skip_files
|
||||
fail_fast: testing.fail_fast
|
||||
show_stats: '-stats' in vargs.split(' ')
|
||||
show_asserts: '-show-asserts' in vargs.split(' ')
|
||||
vargs: vargs
|
||||
vtmp_dir: new_vtmp_dir
|
||||
hash: hash
|
||||
silent_mode: _vargs.contains('-silent')
|
||||
progress_mode: _vargs.contains('-progress')
|
||||
}
|
||||
ts.handle_test_runner_option()
|
||||
|
@ -493,7 +493,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
|
|||
}
|
||||
file := os.real_path(relative_file)
|
||||
mtc := MessageThreadContext{
|
||||
file: file
|
||||
file: file
|
||||
flow_id: thread_id.str()
|
||||
}
|
||||
normalised_relative_file := relative_file.replace('\\', '/')
|
||||
|
|
|
@ -44,15 +44,15 @@ mut:
|
|||
|
||||
fn (mut c Context) compile_oldv_if_needed() {
|
||||
c.vgcontext = vgit.VGitContext{
|
||||
workdir: c.vgo.workdir
|
||||
v_repo_url: c.vgo.v_repo_url
|
||||
vc_repo_url: c.vgo.vc_repo_url
|
||||
cc: c.cc
|
||||
commit_v: c.commit_v
|
||||
path_v: c.path_v
|
||||
path_vc: c.path_vc
|
||||
workdir: c.vgo.workdir
|
||||
v_repo_url: c.vgo.v_repo_url
|
||||
vc_repo_url: c.vgo.vc_repo_url
|
||||
cc: c.cc
|
||||
commit_v: c.commit_v
|
||||
path_v: c.path_v
|
||||
path_vc: c.path_vc
|
||||
make_fresh_tcc: c.fresh_tcc
|
||||
show_vccommit: c.show_vccommit
|
||||
show_vccommit: c.show_vccommit
|
||||
}
|
||||
c.vgcontext.compile_oldv_if_needed()
|
||||
c.commit_v_hash = c.vgcontext.commit_v__hash
|
||||
|
|
|
@ -25,9 +25,9 @@ mut:
|
|||
|
||||
fn new_context() Context {
|
||||
return Context{
|
||||
cwd: os.getwd()
|
||||
cwd: os.getwd()
|
||||
commit_after: 'master'
|
||||
warmups: 4
|
||||
warmups: 4
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,12 +80,12 @@ fn (c &Context) prepare_v(cdir string, commit string) {
|
|||
cc = 'cc'
|
||||
}
|
||||
mut vgit_context := vgit.VGitContext{
|
||||
cc: cc
|
||||
commit_v: commit
|
||||
path_v: cdir
|
||||
path_vc: c.vc
|
||||
workdir: c.vgo.workdir
|
||||
v_repo_url: c.vgo.v_repo_url
|
||||
cc: cc
|
||||
commit_v: commit
|
||||
path_v: cdir
|
||||
path_vc: c.vc
|
||||
workdir: c.vgo.workdir
|
||||
v_repo_url: c.vgo.v_repo_url
|
||||
vc_repo_url: c.vgo.vc_repo_url
|
||||
}
|
||||
vgit_context.compile_oldv_if_needed()
|
||||
|
|
|
@ -126,9 +126,9 @@ fn json(file string) string {
|
|||
pref_.is_fmt = true
|
||||
|
||||
mut t := Tree{
|
||||
root: new_object()
|
||||
root: new_object()
|
||||
table: ast.new_table()
|
||||
pref: pref_
|
||||
pref: pref_
|
||||
}
|
||||
// parse file with comment
|
||||
ast_file := parser.parse_file(file, mut t.table, .parse_comments, t.pref)
|
||||
|
|
|
@ -144,10 +144,10 @@ Try ${tool_name} -h for more help...')
|
|||
|
||||
options := Options{
|
||||
show_help: fp.bool('help', `h`, false, 'Show this help text.')
|
||||
patch: fp.bool('patch', `p`, false, 'Bump the patch version.')
|
||||
minor: fp.bool('minor', `n`, false, 'Bump the minor version.')
|
||||
major: fp.bool('major', `m`, false, 'Bump the major version.')
|
||||
skip: fp.string('skip', `s`, '', 'Skip lines matching this substring.').trim_space()
|
||||
patch: fp.bool('patch', `p`, false, 'Bump the patch version.')
|
||||
minor: fp.bool('minor', `n`, false, 'Bump the minor version.')
|
||||
major: fp.bool('major', `m`, false, 'Bump the major version.')
|
||||
skip: fp.string('skip', `s`, '', 'Skip lines matching this substring.').trim_space()
|
||||
}
|
||||
|
||||
remaining := fp.finalize() or {
|
||||
|
|
|
@ -23,7 +23,7 @@ struct BumpTestCase {
|
|||
const test_cases = [
|
||||
BumpTestCase{
|
||||
file_name: 'v.mod'
|
||||
contents: "Module {
|
||||
contents: "Module {
|
||||
name: 'Sample'
|
||||
description: 'Sample project'
|
||||
version: '1.2.6'
|
||||
|
@ -32,28 +32,28 @@ const test_cases = [
|
|||
}
|
||||
|
||||
"
|
||||
line: 3
|
||||
line: 3
|
||||
expected_patch: " version: '1.2.7'"
|
||||
expected_minor: " version: '1.3.0'"
|
||||
expected_major: " version: '2.0.0'"
|
||||
},
|
||||
BumpTestCase{
|
||||
file_name: 'random_versions.vv'
|
||||
contents: "
|
||||
contents: "
|
||||
1.1.2
|
||||
1.2.5
|
||||
3.21.73
|
||||
version = '1.5.1'
|
||||
|
||||
"
|
||||
line: 4
|
||||
line: 4
|
||||
expected_patch: "version = '1.5.2'"
|
||||
expected_minor: "version = '1.6.0'"
|
||||
expected_major: "version = '2.0.0'"
|
||||
},
|
||||
BumpTestCase{
|
||||
file_name: 'sample_tool.v'
|
||||
contents: "// Module comment and copyright information
|
||||
contents: "// Module comment and copyright information
|
||||
import os
|
||||
import flag
|
||||
|
||||
|
@ -64,7 +64,7 @@ fn main() {
|
|||
// stuff
|
||||
}
|
||||
"
|
||||
line: 5
|
||||
line: 5
|
||||
expected_patch: "const tool_version = '0.1.34'"
|
||||
expected_minor: "const tool_version = '0.2.0'"
|
||||
expected_major: "const tool_version = '1.0.0'"
|
||||
|
@ -111,7 +111,7 @@ struct SkipTestCase {
|
|||
const skip_test_cases = [
|
||||
SkipTestCase{
|
||||
file_name: 'CITATION.cff'
|
||||
contents: 'abstract: A sample CLI tool made in V that prints geometric shapes to the screen.
|
||||
contents: 'abstract: A sample CLI tool made in V that prints geometric shapes to the screen.
|
||||
authors:
|
||||
- alias: hungrybluedev
|
||||
family-names: Haldar
|
||||
|
@ -125,8 +125,8 @@ title: geo
|
|||
url: https://github.com/hungrybluedev/geo
|
||||
version: 0.2.4
|
||||
'
|
||||
line: 12
|
||||
skip: 'cff-version'
|
||||
line: 12
|
||||
skip: 'cff-version'
|
||||
expected_patch: 'version: 0.2.5'
|
||||
expected_minor: 'version: 0.3.0'
|
||||
expected_major: 'version: 1.0.0'
|
||||
|
|
|
@ -34,10 +34,10 @@ pub mut:
|
|||
|
||||
fn (v1 CheckResult) + (v2 CheckResult) CheckResult {
|
||||
return CheckResult{
|
||||
files: v1.files + v2.files
|
||||
files: v1.files + v2.files
|
||||
warnings: v1.warnings + v2.warnings
|
||||
errors: v1.errors + v2.errors
|
||||
oks: v1.oks + v2.oks
|
||||
errors: v1.errors + v2.errors
|
||||
oks: v1.oks + v2.oks
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,8 @@ fn main() {
|
|||
}
|
||||
mut mdfile := MDFile{
|
||||
skip_line_length_check: skip_line_length_check
|
||||
path: file_path
|
||||
lines: lines
|
||||
path: file_path
|
||||
lines: lines
|
||||
}
|
||||
res += mdfile.check()
|
||||
}
|
||||
|
@ -243,7 +243,7 @@ fn (mut f MDFile) parse_line(lnumber int, line string) {
|
|||
command += ' ${default_command}'
|
||||
}
|
||||
f.current = VCodeExample{
|
||||
sline: lnumber
|
||||
sline: lnumber
|
||||
command: command
|
||||
}
|
||||
}
|
||||
|
@ -305,7 +305,7 @@ fn (mut ad AnchorData) add_links(line_number int, line string) {
|
|||
re.match_string(elem)
|
||||
link := re.get_group_by_name(elem, 'link')
|
||||
ad.links[link] << AnchorLink{
|
||||
line: line_number
|
||||
line: line_number
|
||||
label: re.get_group_by_name(elem, 'label')
|
||||
}
|
||||
}
|
||||
|
@ -317,7 +317,7 @@ fn (mut ad AnchorData) add_link_targets(line_number int, line string) {
|
|||
headline := line.substr(headline_start_pos + 1, line.len)
|
||||
link := create_ref_link(headline)
|
||||
ad.anchors[link] << Headline{
|
||||
line: line_number
|
||||
line: line_number
|
||||
label: headline
|
||||
level: headline_start_pos
|
||||
}
|
||||
|
@ -634,7 +634,7 @@ fn (mut f MDFile) check_examples() CheckResult {
|
|||
}
|
||||
return CheckResult{
|
||||
errors: errors
|
||||
oks: oks
|
||||
oks: oks
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -81,9 +81,9 @@ fn (mut ctx Context) process_target(tfile string) ! {
|
|||
for {
|
||||
row := reader.read() or { break }
|
||||
mut cline := CounterLine{
|
||||
meta: row[0]
|
||||
meta: row[0]
|
||||
point: row[1].int()
|
||||
hits: row[2].u64()
|
||||
hits: row[2].u64()
|
||||
}
|
||||
m := ctx.meta[cline.meta] or {
|
||||
ctx.verbose('> skipping invalid meta: ${cline.meta} in file: ${cline.file}, csvfile: ${tfile}')
|
||||
|
|
|
@ -5,7 +5,7 @@ import os
|
|||
fn (mut c Create) set_bin_project_files() {
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: os.join_path(base, 'src', 'main.v')
|
||||
path: os.join_path(base, 'src', 'main.v')
|
||||
content: "module main
|
||||
|
||||
fn main() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import os
|
|||
fn (mut c Create) set_lib_project_files() {
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: os.join_path(base, 'src', c.name + '.v')
|
||||
path: os.join_path(base, 'src', c.name + '.v')
|
||||
content: 'module ${c.name}
|
||||
|
||||
// square calculates the second power of `x`
|
||||
|
@ -15,7 +15,7 @@ pub fn square(x int) int {
|
|||
'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: os.join_path(base, 'tests', 'square_test.v')
|
||||
path: os.join_path(base, 'tests', 'square_test.v')
|
||||
content: 'import ${c.name}
|
||||
|
||||
fn test_square() {
|
||||
|
|
|
@ -5,7 +5,7 @@ import os { join_path }
|
|||
fn (mut c Create) set_web_project_files() {
|
||||
base := if c.new_dir { c.name } else { '' }
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'databases', 'config_databases_sqlite.v')
|
||||
path: join_path(base, 'src', 'databases', 'config_databases_sqlite.v')
|
||||
content: "module databases
|
||||
|
||||
import db.sqlite // can change to 'db.mysql', 'db.pg'
|
||||
|
@ -17,7 +17,7 @@ pub fn create_db_connection() !sqlite.DB {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'templates', 'header_component.html')
|
||||
path: join_path(base, 'src', 'templates', 'header_component.html')
|
||||
content: "<nav>
|
||||
<div class='nav-wrapper'>
|
||||
<a href='javascript:window.history.back();' class='left'>
|
||||
|
@ -36,7 +36,7 @@ pub fn create_db_connection() !sqlite.DB {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'templates', 'products.css')
|
||||
path: join_path(base, 'src', 'templates', 'products.css')
|
||||
content: 'h1.title {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
color: #3b7bbf;
|
||||
|
@ -50,7 +50,7 @@ div.products-table {
|
|||
}'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'templates', 'products.html')
|
||||
path: join_path(base, 'src', 'templates', 'products.html')
|
||||
content: "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
@ -147,7 +147,7 @@ div.products-table {
|
|||
</html>"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'auth_controllers.v')
|
||||
path: join_path(base, 'src', 'auth_controllers.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
|
@ -164,7 +164,7 @@ pub fn (mut app App) controller_auth(username string, password string) vweb.Resu
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'auth_dto.v')
|
||||
path: join_path(base, 'src', 'auth_dto.v')
|
||||
content: 'module main
|
||||
|
||||
struct AuthRequestDto {
|
||||
|
@ -174,7 +174,7 @@ struct AuthRequestDto {
|
|||
'
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'auth_services.v')
|
||||
path: join_path(base, 'src', 'auth_services.v')
|
||||
content: "module main
|
||||
|
||||
import crypto.hmac
|
||||
|
@ -269,7 +269,7 @@ fn auth_verify(token string) bool {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'index.html')
|
||||
path: join_path(base, 'src', 'index.html')
|
||||
content: "<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
|
@ -348,7 +348,7 @@ fn auth_verify(token string) bool {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'main.v')
|
||||
path: join_path(base, 'src', 'main.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
|
@ -391,7 +391,7 @@ pub fn (mut app App) index() vweb.Result {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'product_controller.v')
|
||||
path: join_path(base, 'src', 'product_controller.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
|
@ -457,7 +457,7 @@ pub fn (mut app App) controller_create_product(product_name string) vweb.Result
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'product_entities.v')
|
||||
path: join_path(base, 'src', 'product_entities.v')
|
||||
content: "module main
|
||||
|
||||
@[table: 'products']
|
||||
|
@ -470,7 +470,7 @@ struct Product {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'product_service.v')
|
||||
path: join_path(base, 'src', 'product_service.v')
|
||||
content: "module main
|
||||
|
||||
import databases
|
||||
|
@ -517,7 +517,7 @@ fn (mut app App) service_get_all_products_from(user_id int) ![]Product {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'product_view_api.v')
|
||||
path: join_path(base, 'src', 'product_view_api.v')
|
||||
content: "module main
|
||||
|
||||
import json
|
||||
|
@ -556,7 +556,7 @@ pub fn get_product(token string) ![]User {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'product_view.v')
|
||||
path: join_path(base, 'src', 'product_view.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
|
@ -578,7 +578,7 @@ pub fn (mut app App) products() !vweb.Result {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'user_controllers.v')
|
||||
path: join_path(base, 'src', 'user_controllers.v')
|
||||
content: "module main
|
||||
|
||||
import vweb
|
||||
|
@ -648,7 +648,7 @@ pub fn (mut app App) controller_create_user(username string, password string) vw
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'user_entities.v')
|
||||
path: join_path(base, 'src', 'user_entities.v')
|
||||
content: "module main
|
||||
|
||||
@[table: 'users']
|
||||
|
@ -663,7 +663,7 @@ mut:
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'user_services.v')
|
||||
path: join_path(base, 'src', 'user_services.v')
|
||||
content: "module main
|
||||
|
||||
import crypto.bcrypt
|
||||
|
@ -732,7 +732,7 @@ fn (mut app App) service_get_user(id int) !User {
|
|||
"
|
||||
}
|
||||
c.files << ProjectFiles{
|
||||
path: join_path(base, 'src', 'user_view_api.v')
|
||||
path: join_path(base, 'src', 'user_view_api.v')
|
||||
content: "module main
|
||||
|
||||
import json
|
||||
|
|
|
@ -34,35 +34,35 @@ enum Template {
|
|||
fn main() {
|
||||
flags := [
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'bin'
|
||||
flag: .bool
|
||||
name: 'bin'
|
||||
description: 'Use the template for an executable application [default].'
|
||||
},
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'lib'
|
||||
flag: .bool
|
||||
name: 'lib'
|
||||
description: 'Use the template for a library project.'
|
||||
},
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'web'
|
||||
flag: .bool
|
||||
name: 'web'
|
||||
description: 'Use the template for a vweb project.'
|
||||
},
|
||||
]
|
||||
mut cmd := Command{
|
||||
flags: [
|
||||
Flag{
|
||||
flag: .bool
|
||||
name: 'help'
|
||||
flag: .bool
|
||||
name: 'help'
|
||||
description: 'Print help information.'
|
||||
global: true
|
||||
global: true
|
||||
},
|
||||
]
|
||||
posix_mode: true
|
||||
commands: [
|
||||
commands: [
|
||||
Command{
|
||||
name: 'new'
|
||||
usage: '<project_name>'
|
||||
name: 'new'
|
||||
usage: '<project_name>'
|
||||
description: [
|
||||
'Creates a new V project in a directory with the specified project name.',
|
||||
'',
|
||||
|
@ -73,13 +73,13 @@ fn main() {
|
|||
parent: &Command{
|
||||
name: 'v'
|
||||
}
|
||||
posix_mode: true
|
||||
flags: flags
|
||||
posix_mode: true
|
||||
flags: flags
|
||||
pre_execute: validate
|
||||
execute: new_project
|
||||
execute: new_project
|
||||
},
|
||||
Command{
|
||||
name: 'init'
|
||||
name: 'init'
|
||||
description: [
|
||||
'Sets up a V project within the current directory.',
|
||||
'',
|
||||
|
@ -90,10 +90,10 @@ fn main() {
|
|||
parent: &Command{
|
||||
name: 'v'
|
||||
}
|
||||
posix_mode: true
|
||||
flags: flags
|
||||
posix_mode: true
|
||||
flags: flags
|
||||
pre_execute: validate
|
||||
execute: init_project
|
||||
execute: init_project
|
||||
},
|
||||
]
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ fn validate(cmd Command) ! {
|
|||
fn new_project(cmd Command) ! {
|
||||
mut c := Create{
|
||||
template: get_template(cmd)
|
||||
new_dir: true
|
||||
new_dir: true
|
||||
}
|
||||
c.prompt(cmd.args)
|
||||
println('Initialising ...')
|
||||
|
|
|
@ -134,7 +134,7 @@ fn (mut vd VDoc) collect_search_index(out Output) {
|
|||
}
|
||||
vd.search_module_data << SearchModuleResult{
|
||||
description: trim_doc_node_description(mod, comments)
|
||||
link: vd.get_file_name(mod, out)
|
||||
link: vd.get_file_name(mod, out)
|
||||
}
|
||||
for _, dn in doc.contents {
|
||||
vd.create_search_results(mod, dn, out)
|
||||
|
@ -155,10 +155,14 @@ fn (mut vd VDoc) create_search_results(mod string, dn doc.DocNode, out Output) {
|
|||
dn_description := trim_doc_node_description(dn.name, comments)
|
||||
vd.search_index << dn.name
|
||||
vd.search_data << SearchResult{
|
||||
prefix: if dn.parent_name != '' { '${dn.kind} (${dn.parent_name})' } else { '${dn.kind} ' }
|
||||
prefix: if dn.parent_name != '' {
|
||||
'${dn.kind} (${dn.parent_name})'
|
||||
} else {
|
||||
'${dn.kind} '
|
||||
}
|
||||
description: dn_description
|
||||
badge: mod
|
||||
link: vd.get_file_name(mod, out) + '#' + get_node_id(dn)
|
||||
badge: mod
|
||||
link: vd.get_file_name(mod, out) + '#' + get_node_id(dn)
|
||||
}
|
||||
for child in dn.children {
|
||||
vd.create_search_results(mod, child, out)
|
||||
|
|
|
@ -55,7 +55,7 @@ fn main() {
|
|||
}
|
||||
// Config is immutable from this point on
|
||||
mut vd := &VDoc{
|
||||
cfg: cfg
|
||||
cfg: cfg
|
||||
manifest: vmod.Manifest{}
|
||||
}
|
||||
vd.vprintln('Setting output type to "${cfg.output_type}"')
|
||||
|
|
|
@ -258,7 +258,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
|||
cfg := vd.cfg
|
||||
mut out := Output{
|
||||
path: cfg.output_path
|
||||
typ: cfg.output_type
|
||||
typ: cfg.output_type
|
||||
}
|
||||
if out.path == '' {
|
||||
if cfg.output_type == .unset {
|
||||
|
@ -300,7 +300,7 @@ fn (mut vd VDoc) generate_docs_from_file() {
|
|||
} else if out.typ == .html && cfg.is_multi {
|
||||
vd.docs << doc.Doc{
|
||||
head: doc.DocNode{
|
||||
name: 'README'
|
||||
name: 'README'
|
||||
comments: [comment]
|
||||
}
|
||||
time_generated: time.now()
|
||||
|
|
|
@ -51,7 +51,7 @@ fn (mut a App) collect_info() {
|
|||
if os_kind == 'windows' {
|
||||
arch_details << a.cmd(
|
||||
command: 'wmic cpu get name /format:table'
|
||||
line: 1
|
||||
line: 1
|
||||
)
|
||||
}
|
||||
//
|
||||
|
@ -87,7 +87,7 @@ fn (mut a App) collect_info() {
|
|||
} else if os_kind == 'windows' {
|
||||
wmic_info := a.cmd(
|
||||
command: 'wmic os get * /format:value'
|
||||
line: -1
|
||||
line: -1
|
||||
)
|
||||
p := a.parse(wmic_info, '=')
|
||||
caption, build_number, os_arch := p['caption'], p['buildnumber'], p['osarchitecture']
|
||||
|
|
|
@ -44,16 +44,16 @@ fn main() {
|
|||
util.set_vroot_folder(os.dir(os.dir(os.dir(toolexe))))
|
||||
args := util.join_env_vflags_and_os_args()
|
||||
mut foptions := FormatOptions{
|
||||
is_c: '-c' in args
|
||||
is_l: '-l' in args
|
||||
is_w: '-w' in args
|
||||
is_diff: '-diff' in args
|
||||
is_c: '-c' in args
|
||||
is_l: '-l' in args
|
||||
is_w: '-w' in args
|
||||
is_diff: '-diff' in args
|
||||
is_verbose: '-verbose' in args || '--verbose' in args
|
||||
is_worker: '-worker' in args
|
||||
is_debug: '-debug' in args
|
||||
is_worker: '-worker' in args
|
||||
is_debug: '-debug' in args
|
||||
is_noerror: '-noerror' in args
|
||||
is_verify: '-verify' in args
|
||||
is_backup: '-backup' in args
|
||||
is_verify: '-verify' in args
|
||||
is_backup: '-backup' in args
|
||||
in_process: '-inprocess' in args
|
||||
}
|
||||
if term_colors {
|
||||
|
|
|
@ -162,9 +162,9 @@ fn main() {
|
|||
|
||||
// Collect tool options
|
||||
mut opt := Options{
|
||||
verbose: fp.bool('verbose', `v`, false, "Be verbose about the tool's progress.")
|
||||
verbose: fp.bool('verbose', `v`, false, "Be verbose about the tool's progress.")
|
||||
compare_only: fp.bool('compare-only', `c`, false, "Don't generate screenshots - only compare input directories")
|
||||
root_path: fp.string('root-path', `r`, v_root, 'Root path of the comparison')
|
||||
root_path: fp.string('root-path', `r`, v_root, 'Root path of the comparison')
|
||||
}
|
||||
|
||||
toml_conf := fp.string('toml-config', `t`, default_toml, 'Path or string with TOML configuration')
|
||||
|
@ -446,7 +446,7 @@ fn new_config(root_path string, toml_config string) !Config {
|
|||
compare_flags := doc.value('compare.flags').default_to(empty_toml_array).array().as_strings()
|
||||
default_compare := CompareOptions{
|
||||
method: compare_method
|
||||
flags: compare_flags
|
||||
flags: compare_flags
|
||||
}
|
||||
capture_method := doc.value('capture.method').default_to('gg_record').string()
|
||||
capture_flags := doc.value('capture.flags').default_to(empty_toml_array).array().as_strings()
|
||||
|
@ -454,9 +454,9 @@ fn new_config(root_path string, toml_config string) !Config {
|
|||
mut capture_regions := []CaptureRegion{}
|
||||
for capture_region_any in capture_regions_any {
|
||||
region := CaptureRegion{
|
||||
x: capture_region_any.value('x').default_to(0).int()
|
||||
y: capture_region_any.value('y').default_to(0).int()
|
||||
width: capture_region_any.value('width').default_to(0).int()
|
||||
x: capture_region_any.value('x').default_to(0).int()
|
||||
y: capture_region_any.value('y').default_to(0).int()
|
||||
width: capture_region_any.value('width').default_to(0).int()
|
||||
height: capture_region_any.value('height').default_to(0).int()
|
||||
}
|
||||
capture_regions << region
|
||||
|
@ -468,11 +468,11 @@ fn new_config(root_path string, toml_config string) !Config {
|
|||
env_map[k] = v.string()
|
||||
}
|
||||
default_capture := CaptureOptions{
|
||||
method: capture_method
|
||||
method: capture_method
|
||||
wait_ms: capture_wait_ms
|
||||
flags: capture_flags
|
||||
flags: capture_flags
|
||||
regions: capture_regions
|
||||
env: env_map
|
||||
env: env_map
|
||||
}
|
||||
|
||||
apps_any := doc.value('apps').default_to(empty_toml_array).array()
|
||||
|
@ -503,9 +503,9 @@ fn new_config(root_path string, toml_config string) !Config {
|
|||
mut app_capture_regions := []CaptureRegion{}
|
||||
for capture_region_any in app_capture_regions_any {
|
||||
region := CaptureRegion{
|
||||
x: capture_region_any.value('x').default_to(0).int()
|
||||
y: capture_region_any.value('y').default_to(0).int()
|
||||
width: capture_region_any.value('width').default_to(0).int()
|
||||
x: capture_region_any.value('x').default_to(0).int()
|
||||
y: capture_region_any.value('y').default_to(0).int()
|
||||
width: capture_region_any.value('width').default_to(0).int()
|
||||
height: capture_region_any.value('height').default_to(0).int()
|
||||
}
|
||||
app_capture_regions << region
|
||||
|
@ -536,9 +536,9 @@ fn new_config(root_path string, toml_config string) !Config {
|
|||
merged_capture.validate()!
|
||||
|
||||
app_config := AppConfig{
|
||||
compare: merged_compare
|
||||
capture: merged_capture
|
||||
path: rel_path
|
||||
compare: merged_compare
|
||||
capture: merged_capture
|
||||
path: rel_path
|
||||
abs_path: os.join_path(path, rel_path).trim_right('/')
|
||||
}
|
||||
apps << app_config
|
||||
|
|
|
@ -63,9 +63,9 @@ const server_not_found_err = error_with_code('Language server is not installed n
|
|||
101)
|
||||
|
||||
const json_enc = json2.Encoder{
|
||||
newline: `\n`
|
||||
newline: `\n`
|
||||
newline_spaces_count: 2
|
||||
escape_unicode: false
|
||||
escape_unicode: false
|
||||
}
|
||||
|
||||
fn (upd VlsUpdater) check_or_create_vls_folder() ! {
|
||||
|
|
|
@ -74,10 +74,10 @@ fn (opt &Options) collect_undocumented_functions_in_file(nfile string) []Undocum
|
|||
if comments.len == 0 {
|
||||
clean_line := line.all_before_last(' {')
|
||||
list << UndocumentedFN{
|
||||
line: i + 1
|
||||
line: i + 1
|
||||
signature: clean_line
|
||||
tags: tags
|
||||
file: file
|
||||
tags: tags
|
||||
file: file
|
||||
}
|
||||
}
|
||||
tags = []
|
||||
|
@ -229,16 +229,16 @@ fn main() {
|
|||
|
||||
// Collect tool options
|
||||
mut opt := Options{
|
||||
show_help: fp.bool('help', `h`, false, 'Show this help text.')
|
||||
deprecated: fp.bool('deprecated', `d`, false, 'Include deprecated functions in output.')
|
||||
private: fp.bool('private', `p`, false, 'Include private functions in output.')
|
||||
js: fp.bool('js', 0, false, 'Include JavaScript functions in output.')
|
||||
show_help: fp.bool('help', `h`, false, 'Show this help text.')
|
||||
deprecated: fp.bool('deprecated', `d`, false, 'Include deprecated functions in output.')
|
||||
private: fp.bool('private', `p`, false, 'Include private functions in output.')
|
||||
js: fp.bool('js', 0, false, 'Include JavaScript functions in output.')
|
||||
no_line_numbers: fp.bool('no-line-numbers', `n`, false, 'Exclude line numbers in output.')
|
||||
collect_tags: fp.bool('tags', `t`, false, 'Also print function tags if any is found.')
|
||||
exclude: fp.string_multi('exclude', `e`, '')
|
||||
relative_paths: fp.bool('relative-paths', `r`, false, 'Use relative paths in output.')
|
||||
diff: fp.bool('diff', 0, false, 'exit(1) and show difference between two PATH inputs, return 0 otherwise.')
|
||||
verify: fp.bool('verify', 0, false, 'exit(1) if documentation is missing, 0 otherwise.')
|
||||
collect_tags: fp.bool('tags', `t`, false, 'Also print function tags if any is found.')
|
||||
exclude: fp.string_multi('exclude', `e`, '')
|
||||
relative_paths: fp.bool('relative-paths', `r`, false, 'Use relative paths in output.')
|
||||
diff: fp.bool('diff', 0, false, 'exit(1) and show difference between two PATH inputs, return 0 otherwise.')
|
||||
verify: fp.bool('verify', 0, false, 'exit(1) if documentation is missing, 0 otherwise.')
|
||||
}
|
||||
|
||||
opt.additional_args = fp.finalize() or { panic(err) }
|
||||
|
|
|
@ -114,13 +114,13 @@ fn (mut p Parser) parse_module(m string) {
|
|||
mod_path := normalize_mod_path(os.join_path(if kind == .http { publisher } else { '' },
|
||||
manifest.name))
|
||||
Module{
|
||||
name: manifest.name
|
||||
url: ident
|
||||
version: version
|
||||
name: manifest.name
|
||||
url: ident
|
||||
version: version
|
||||
install_path: os.real_path(os.join_path(settings.vmodules_path, mod_path))
|
||||
is_external: true
|
||||
tmp_path: tmp_path
|
||||
manifest: manifest
|
||||
is_external: true
|
||||
tmp_path: tmp_path
|
||||
manifest: manifest
|
||||
}
|
||||
} else {
|
||||
// VPM registered module.
|
||||
|
@ -170,13 +170,13 @@ fn (mut p Parser) parse_module(m string) {
|
|||
vmod.Manifest{}
|
||||
}
|
||||
Module{
|
||||
name: info.name
|
||||
url: info.url
|
||||
version: version
|
||||
vcs: vcs
|
||||
name: info.name
|
||||
url: info.url
|
||||
version: version
|
||||
vcs: vcs
|
||||
install_path: os.real_path(os.join_path(settings.vmodules_path, mod_path))
|
||||
tmp_path: tmp_path
|
||||
manifest: manifest
|
||||
tmp_path: tmp_path
|
||||
manifest: manifest
|
||||
}
|
||||
}
|
||||
mod.install_path_fmted = fmt_mod_path(mod.install_path)
|
||||
|
|
|
@ -44,16 +44,16 @@ fn init_settings() VpmSettings {
|
|||
}
|
||||
|
||||
return VpmSettings{
|
||||
is_help: '-h' in opts || '--help' in opts || 'help' in cmds
|
||||
is_once: '--once' in opts
|
||||
is_verbose: '-v' in opts || '--verbose' in opts
|
||||
is_force: '-f' in opts || '--force' in opts
|
||||
server_urls: cmdline.options(args, '--server-urls')
|
||||
vcs: if '--hg' in opts { .hg } else { .git }
|
||||
vmodules_path: vmodules_path
|
||||
tmp_path: os.join_path(os.vtmp_dir(), 'vpm_modules')
|
||||
is_help: '-h' in opts || '--help' in opts || 'help' in cmds
|
||||
is_once: '--once' in opts
|
||||
is_verbose: '-v' in opts || '--verbose' in opts
|
||||
is_force: '-f' in opts || '--force' in opts
|
||||
server_urls: cmdline.options(args, '--server-urls')
|
||||
vcs: if '--hg' in opts { .hg } else { .git }
|
||||
vmodules_path: vmodules_path
|
||||
tmp_path: os.join_path(os.vtmp_dir(), 'vpm_modules')
|
||||
no_dl_count_increment: is_ci || is_no_inc
|
||||
fail_on_prompt: os.getenv('VPM_FAIL_ON_PROMPT') != ''
|
||||
logger: logger
|
||||
fail_on_prompt: os.getenv('VPM_FAIL_ON_PROMPT') != ''
|
||||
logger: logger
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,22 +35,22 @@ fn init_vcs_info() !map[VCS]VCSInfo {
|
|||
}
|
||||
return {
|
||||
VCS.git: VCSInfo{
|
||||
dir: '.git'
|
||||
dir: '.git'
|
||||
args: struct {
|
||||
install: git_install_cmd
|
||||
version: '--single-branch -b'
|
||||
update: 'pull --recurse-submodules' // pulling with `--depth=1` leads to conflicts when the upstream has more than 1 new commits.
|
||||
path: '-C'
|
||||
install: git_install_cmd
|
||||
version: '--single-branch -b'
|
||||
update: 'pull --recurse-submodules' // pulling with `--depth=1` leads to conflicts when the upstream has more than 1 new commits.
|
||||
path: '-C'
|
||||
outdated: ['fetch', 'rev-parse @', 'rev-parse @{u}']
|
||||
}
|
||||
}
|
||||
VCS.hg: VCSInfo{
|
||||
dir: '.hg'
|
||||
dir: '.hg'
|
||||
args: struct {
|
||||
install: 'clone'
|
||||
version: '--rev'
|
||||
update: 'pull --update'
|
||||
path: '-R'
|
||||
install: 'clone'
|
||||
version: '--rev'
|
||||
update: 'pull --update'
|
||||
path: '-R'
|
||||
outdated: ['incoming']
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,8 +59,8 @@ mut:
|
|||
fn new_aints(ovals []i64, extreme_mins int, extreme_maxs int) Aints {
|
||||
mut res := Aints{
|
||||
values: ovals // remember the original values
|
||||
nmins: extreme_mins
|
||||
nmaxs: extreme_maxs
|
||||
nmins: extreme_mins
|
||||
nmaxs: extreme_maxs
|
||||
}
|
||||
// discard the extremes, if needed:
|
||||
mut vals := []i64{}
|
||||
|
|
|
@ -90,8 +90,8 @@ fn new_repl(folder string) Repl {
|
|||
readline: readline.Readline{
|
||||
skip_empty: true
|
||||
}
|
||||
folder: folder
|
||||
modules: ['os', 'time', 'math']
|
||||
folder: folder
|
||||
modules: ['os', 'time', 'math']
|
||||
vstartup_lines: vstartup_source
|
||||
// Test file used to check if a function as a void return or a value return.
|
||||
eval_func_lines: vstartup_source
|
||||
|
|
|
@ -84,10 +84,10 @@ fn main() {
|
|||
fp.skip_executable()
|
||||
// Collect tool options
|
||||
opt := Options{
|
||||
show_help: fp.bool('help', `h`, false, 'Show this help text.')
|
||||
show_help: fp.bool('help', `h`, false, 'Show this help text.')
|
||||
force_update: fp.bool('force-update', `u`, false, 'Force update of the sokol-shdc tool.')
|
||||
verbose: fp.bool('verbose', `v`, false, 'Be verbose about the tools progress.')
|
||||
slangs: fp.string_multi('slang', `l`, 'Shader dialects to generate code for. Default is all.\n Available dialects: ${supported_slangs}')
|
||||
verbose: fp.bool('verbose', `v`, false, 'Be verbose about the tools progress.')
|
||||
slangs: fp.string_multi('slang', `l`, 'Shader dialects to generate code for. Default is all.\n Available dialects: ${supported_slangs}')
|
||||
}
|
||||
if opt.show_help {
|
||||
println(fp.usage())
|
||||
|
@ -161,8 +161,8 @@ fn compile_shaders(opt Options, input_path string) ! {
|
|||
continue
|
||||
}
|
||||
co := CompileOptions{
|
||||
verbose: opt.verbose
|
||||
slangs: opt.slangs
|
||||
verbose: opt.verbose
|
||||
slangs: opt.slangs
|
||||
invoke_path: path
|
||||
}
|
||||
// Currently sokol-shdc allows for multiple --input flags
|
||||
|
|
|
@ -86,15 +86,15 @@ mut:
|
|||
fn get_all_commands() []Command {
|
||||
mut res := []Command{}
|
||||
res << Command{
|
||||
line: '${vexe} examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world.'
|
||||
line: '${vexe} examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world.'
|
||||
rmfile: 'examples/hello_world'
|
||||
}
|
||||
$if linux {
|
||||
if l2w_crosscc != '' {
|
||||
res << Command{
|
||||
line: '${vexe} -os windows examples/hello_world.v'
|
||||
okmsg: 'V cross compiles hello_world.v on linux, to a windows .exe file'
|
||||
line: '${vexe} -os windows examples/hello_world.v'
|
||||
okmsg: 'V cross compiles hello_world.v on linux, to a windows .exe file'
|
||||
rmfile: 'examples/hello_world.exe'
|
||||
}
|
||||
} else {
|
||||
|
@ -102,54 +102,54 @@ fn get_all_commands() []Command {
|
|||
}
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o hhww.c examples/hello_world.v'
|
||||
okmsg: 'V can output a .c file, without compiling further.'
|
||||
line: '${vexe} -o hhww.c examples/hello_world.v'
|
||||
okmsg: 'V can output a .c file, without compiling further.'
|
||||
rmfile: 'hhww.c'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world with -skip-unused.'
|
||||
line: '${vexe} -skip-unused examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world with -skip-unused.'
|
||||
rmfile: 'examples/hello_world'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused test vlib/builtin'
|
||||
line: '${vexe} -skip-unused test vlib/builtin'
|
||||
okmsg: 'V can test vlib/builtin with -skip-unused'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused -profile - examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world with both -skip-unused and -profile .'
|
||||
line: '${vexe} -skip-unused -profile - examples/hello_world.v'
|
||||
okmsg: 'V can compile hello world with both -skip-unused and -profile .'
|
||||
rmfile: 'examples/hello_world'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -e "print(84/2)"'
|
||||
okmsg: 'V can run code given after `-e`'
|
||||
line: '${vexe} -e "print(84/2)"'
|
||||
okmsg: 'V can run code given after `-e`'
|
||||
runcmd: .execute
|
||||
expect: '42'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -e "import os; import math; print(os.args#[1..]) print(math.sin(math.pi/2).str())" arg1 arg2'
|
||||
okmsg: 'V can run code with `-e`, that use semicolons and several imports, and that accepts CLI parameters.'
|
||||
line: '${vexe} -e "import os; import math; print(os.args#[1..]) print(math.sin(math.pi/2).str())" arg1 arg2'
|
||||
okmsg: 'V can run code with `-e`, that use semicolons and several imports, and that accepts CLI parameters.'
|
||||
runcmd: .execute
|
||||
expect: "['arg1', 'arg2']1.0"
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o calling_c.exe run examples/call_c_from_v/main.c.v'
|
||||
okmsg: 'V can run main.c.v files'
|
||||
runcmd: .execute
|
||||
line: '${vexe} -o calling_c.exe run examples/call_c_from_v/main.c.v'
|
||||
okmsg: 'V can run main.c.v files'
|
||||
runcmd: .execute
|
||||
contains: 'V can call C functions like `puts` too.'
|
||||
}
|
||||
$if linux || macos {
|
||||
res << Command{
|
||||
line: '${vexe} run examples/hello_world.v'
|
||||
okmsg: 'V can run hello world.'
|
||||
line: '${vexe} run examples/hello_world.v'
|
||||
okmsg: 'V can run hello world.'
|
||||
runcmd: .execute
|
||||
expect: 'Hello, World!\n'
|
||||
}
|
||||
if clang_path != '' {
|
||||
res << Command{
|
||||
line: '${vexe} -os freebsd -gc none examples/hello_world.v'
|
||||
okmsg: 'V cross compiles hello_world.v, to a FreeBSD executable'
|
||||
rmfile: 'examples/hello_world'
|
||||
line: '${vexe} -os freebsd -gc none examples/hello_world.v'
|
||||
okmsg: 'V cross compiles hello_world.v, to a FreeBSD executable'
|
||||
rmfile: 'examples/hello_world'
|
||||
after_cb: fn () ! {
|
||||
for file in ['examples/hello_world',
|
||||
os.join_path(os.vmodules_dir(), 'freebsdroot/usr/include/stdio.h')] {
|
||||
|
@ -166,8 +166,8 @@ fn get_all_commands() []Command {
|
|||
for compiler_name in ['clang', 'gcc'] {
|
||||
if _ := os.find_abs_path_of_executable(compiler_name) {
|
||||
res << Command{
|
||||
line: '${vexe} -cc ${compiler_name} -gc boehm run examples/hello_world.v'
|
||||
okmsg: '`v -cc ${compiler_name} -gc boehm run examples/hello_world.v` works'
|
||||
line: '${vexe} -cc ${compiler_name} -gc boehm run examples/hello_world.v'
|
||||
okmsg: '`v -cc ${compiler_name} -gc boehm run examples/hello_world.v` works'
|
||||
runcmd: .execute
|
||||
expect: 'Hello, World!\n'
|
||||
}
|
||||
|
@ -175,25 +175,25 @@ fn get_all_commands() []Command {
|
|||
}
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} interpret examples/hello_world.v'
|
||||
okmsg: 'V can interpret hello world.'
|
||||
line: '${vexe} interpret examples/hello_world.v'
|
||||
okmsg: 'V can interpret hello world.'
|
||||
runcmd: .execute
|
||||
expect: 'Hello, World!\n'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} interpret examples/hanoi.v'
|
||||
okmsg: 'V can interpret hanoi.v'
|
||||
runcmd: .execute
|
||||
line: '${vexe} interpret examples/hanoi.v'
|
||||
okmsg: 'V can interpret hanoi.v'
|
||||
runcmd: .execute
|
||||
starts_with: 'Disc 1 from A to C...\n'
|
||||
ends_with: 'Disc 1 from A to C...\n'
|
||||
contains: 'Disc 7 from A to C...\n'
|
||||
ends_with: 'Disc 1 from A to C...\n'
|
||||
contains: 'Disc 7 from A to C...\n'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o - examples/hello_world.v | grep "#define V_COMMIT_HASH" > /dev/null'
|
||||
line: '${vexe} -o - examples/hello_world.v | grep "#define V_COMMIT_HASH" > /dev/null'
|
||||
okmsg: 'V prints the generated source code to stdout with `-o -` .'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} run examples/v_script.vsh > /dev/null'
|
||||
line: '${vexe} run examples/v_script.vsh > /dev/null'
|
||||
okmsg: 'V can run the .VSH script file examples/v_script.vsh'
|
||||
}
|
||||
// Note: -experimental is used here, just to suppress the warnings,
|
||||
|
@ -201,13 +201,13 @@ fn get_all_commands() []Command {
|
|||
// until globals and hash statements *are implemented*:
|
||||
$if linux {
|
||||
res << Command{
|
||||
line: '${vexe} -experimental -b native run examples/native/hello_world.v > /dev/null'
|
||||
line: '${vexe} -experimental -b native run examples/native/hello_world.v > /dev/null'
|
||||
okmsg: 'V compiles and runs examples/native/hello_world.v on the native backend for linux'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -no-builtin -experimental -b native examples/hello_world.v > /dev/null'
|
||||
okmsg: 'V compiles examples/hello_world.v on the native backend for linux with `-no-builtin` & the executable is <= ${hw_native_no_builtin_size_limit} bytes'
|
||||
rmfile: 'examples/hello_world'
|
||||
line: '${vexe} -no-builtin -experimental -b native examples/hello_world.v > /dev/null'
|
||||
okmsg: 'V compiles examples/hello_world.v on the native backend for linux with `-no-builtin` & the executable is <= ${hw_native_no_builtin_size_limit} bytes'
|
||||
rmfile: 'examples/hello_world'
|
||||
after_cb: fn () ! {
|
||||
file := 'examples/hello_world'
|
||||
if !os.exists(file) {
|
||||
|
@ -221,88 +221,88 @@ fn get_all_commands() []Command {
|
|||
}
|
||||
// only compilation:
|
||||
res << Command{
|
||||
line: '${vexe} -os linux -experimental -b native -o hw.linux examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for linux'
|
||||
line: '${vexe} -os linux -experimental -b native -o hw.linux examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for linux'
|
||||
rmfile: 'hw.linux'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -os macos -experimental -b native -o hw.macos examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for macos'
|
||||
line: '${vexe} -os macos -experimental -b native -o hw.macos examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for macos'
|
||||
rmfile: 'hw.macos'
|
||||
}
|
||||
$if windows {
|
||||
res << Command{
|
||||
line: '${vexe} -os windows -experimental -b native -o hw.exe examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for windows'
|
||||
line: '${vexe} -os windows -experimental -b native -o hw.exe examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the native backend for windows'
|
||||
rmfile: 'hw.exe'
|
||||
}
|
||||
}
|
||||
//
|
||||
res << Command{
|
||||
line: '${vexe} -b js -o hw.js examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the JS backend'
|
||||
line: '${vexe} -b js -o hw.js examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the JS backend'
|
||||
rmfile: 'hw.js'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused -b js -o hw_skip_unused.js examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the JS backend, with -skip-unused'
|
||||
line: '${vexe} -skip-unused -b js -o hw_skip_unused.js examples/hello_world.v'
|
||||
okmsg: 'V compiles hello_world.v on the JS backend, with -skip-unused'
|
||||
rmfile: 'hw_skip_unused.js'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused examples/2048'
|
||||
okmsg: 'V can compile 2048 with -skip-unused.'
|
||||
line: '${vexe} -skip-unused examples/2048'
|
||||
okmsg: 'V can compile 2048 with -skip-unused.'
|
||||
rmfile: 'examples/2048/2048'
|
||||
}
|
||||
if _ := os.find_abs_path_of_executable('emcc') {
|
||||
res << Command{
|
||||
line: '${vexe} -os wasm32_emscripten examples/2048'
|
||||
okmsg: 'V can compile 2048 with -os wasm32_emscripten, using emcc.'
|
||||
line: '${vexe} -os wasm32_emscripten examples/2048'
|
||||
okmsg: 'V can compile 2048 with -os wasm32_emscripten, using emcc.'
|
||||
rmfile: 'examples/2048/2048'
|
||||
}
|
||||
} else {
|
||||
println('> emcc not found, skipping `v -os wasm32_emscripten examples/2048`.')
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -skip-unused -live examples/hot_reload/bounce.v'
|
||||
okmsg: 'V can compile the hot code reloading bounce.v example with both: -skip-unused -live'
|
||||
line: '${vexe} -skip-unused -live examples/hot_reload/bounce.v'
|
||||
okmsg: 'V can compile the hot code reloading bounce.v example with both: -skip-unused -live'
|
||||
rmfile: 'examples/hot_reload/bounce'
|
||||
}
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o vtmp cmd/v'
|
||||
okmsg: 'V can compile itself.'
|
||||
line: '${vexe} -o vtmp cmd/v'
|
||||
okmsg: 'V can compile itself.'
|
||||
rmfile: 'vtmp'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o vtmp_werror -cstrict cmd/v'
|
||||
okmsg: 'V can compile itself with -cstrict.'
|
||||
line: '${vexe} -o vtmp_werror -cstrict cmd/v'
|
||||
okmsg: 'V can compile itself with -cstrict.'
|
||||
rmfile: 'vtmp_werror'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o vtmp_autofree -autofree cmd/v'
|
||||
okmsg: 'V can compile itself with -autofree.'
|
||||
line: '${vexe} -o vtmp_autofree -autofree cmd/v'
|
||||
okmsg: 'V can compile itself with -autofree.'
|
||||
rmfile: 'vtmp_autofree'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o vtmp_prealloc -prealloc cmd/v'
|
||||
okmsg: 'V can compile itself with -prealloc.'
|
||||
line: '${vexe} -o vtmp_prealloc -prealloc cmd/v'
|
||||
okmsg: 'V can compile itself with -prealloc.'
|
||||
rmfile: 'vtmp_prealloc'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -o vtmp_unused -skip-unused cmd/v'
|
||||
okmsg: 'V can compile itself with -skip-unused.'
|
||||
line: '${vexe} -o vtmp_unused -skip-unused cmd/v'
|
||||
okmsg: 'V can compile itself with -skip-unused.'
|
||||
rmfile: 'vtmp_unused'
|
||||
}
|
||||
$if linux {
|
||||
res << Command{
|
||||
line: '${vexe} -cc gcc -keepc -freestanding -o bel vlib/os/bare/bare_example_linux.v'
|
||||
okmsg: 'V can compile with -freestanding on Linux with GCC.'
|
||||
line: '${vexe} -cc gcc -keepc -freestanding -o bel vlib/os/bare/bare_example_linux.v'
|
||||
okmsg: 'V can compile with -freestanding on Linux with GCC.'
|
||||
rmfile: 'bel'
|
||||
}
|
||||
|
||||
res << Command{
|
||||
line: '${vexe} -cc gcc -keepc -freestanding -o str_array vlib/strconv/bare/str_array_example.v'
|
||||
okmsg: 'V can compile & allocate memory with -freestanding on Linux with GCC.'
|
||||
line: '${vexe} -cc gcc -keepc -freestanding -o str_array vlib/strconv/bare/str_array_example.v'
|
||||
okmsg: 'V can compile & allocate memory with -freestanding on Linux with GCC.'
|
||||
rmfile: 'str_array'
|
||||
}
|
||||
}
|
||||
|
@ -311,15 +311,15 @@ fn get_all_commands() []Command {
|
|||
common_shared_flags := '-shared -skip-unused -d no_backtrace -o library examples/dynamic_library_loader/modules/library/library.v'
|
||||
$if macos {
|
||||
res << Command{
|
||||
line: '${vexe} ${common_shared_flags}'
|
||||
okmsg: 'V compiles library.v with -shared on macos'
|
||||
line: '${vexe} ${common_shared_flags}'
|
||||
okmsg: 'V compiles library.v with -shared on macos'
|
||||
rmfile: 'library.dylib'
|
||||
}
|
||||
}
|
||||
$if linux {
|
||||
res << Command{
|
||||
line: '${vexe} ${common_shared_flags}'
|
||||
okmsg: 'V compiles library.v with -shared on linux'
|
||||
line: '${vexe} ${common_shared_flags}'
|
||||
okmsg: 'V compiles library.v with -shared on linux'
|
||||
rmfile: 'library.so'
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +327,8 @@ fn get_all_commands() []Command {
|
|||
$if linux {
|
||||
if l2w_crosscc != '' {
|
||||
res << Command{
|
||||
line: '${vexe} -os windows ${common_shared_flags}'
|
||||
okmsg: 'V cross compiles library.v with -shared on linux, to a windows library.dll file'
|
||||
line: '${vexe} -os windows ${common_shared_flags}'
|
||||
okmsg: 'V cross compiles library.v with -shared on linux, to a windows library.dll file'
|
||||
rmfile: 'library.dll'
|
||||
}
|
||||
} else {
|
||||
|
@ -337,92 +337,92 @@ fn get_all_commands() []Command {
|
|||
}
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
res << Command{
|
||||
line: '${vexe} ${vargs} -progress test-cleancode'
|
||||
line: '${vexe} ${vargs} -progress test-cleancode'
|
||||
okmsg: 'All .v files are invariant when processed with `v fmt`'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} ${vargs} -progress test-fmt'
|
||||
line: '${vexe} ${vargs} -progress test-fmt'
|
||||
okmsg: 'All .v files can be processed with `v fmt`. Note: the result may not always be compilable, but `v fmt` should not crash.'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} ${vargs} -progress test-self'
|
||||
line: '${vexe} ${vargs} -progress test-self'
|
||||
okmsg: 'There are no _test.v file regressions.'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} ${vargs} -progress -N -W build-tools'
|
||||
line: '${vexe} ${vargs} -progress -N -W build-tools'
|
||||
okmsg: 'All tools can be compiled.'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} ${vargs} -progress -N -W build-examples'
|
||||
line: '${vexe} ${vargs} -progress -N -W build-examples'
|
||||
okmsg: 'All examples can be compiled.'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} check-md -hide-warnings .'
|
||||
line: '${vexe} check-md -hide-warnings .'
|
||||
label: 'Check ```v ``` code examples and formatting of .MD files...'
|
||||
okmsg: 'All .md files look good.'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} install nedpals.args'
|
||||
line: '${vexe} install nedpals.args'
|
||||
okmsg: '`v install` works.'
|
||||
}
|
||||
res << Command{
|
||||
okmsg: 'Running net.http with -d trace_http_request works.'
|
||||
line: '${vexe} -d trace_http_request -e \'import net.http; x := http.fetch(url: "https://vpm.url4e.com/some/unknown/url")!; println(x.status_code)\''
|
||||
runcmd: .execute
|
||||
okmsg: 'Running net.http with -d trace_http_request works.'
|
||||
line: '${vexe} -d trace_http_request -e \'import net.http; x := http.fetch(url: "https://vpm.url4e.com/some/unknown/url")!; println(x.status_code)\''
|
||||
runcmd: .execute
|
||||
starts_with: '> GET /some/unknown/url HTTP/1.1'
|
||||
contains: 'User-Agent: v.http'
|
||||
ends_with: '404\n'
|
||||
contains: 'User-Agent: v.http'
|
||||
ends_with: '404\n'
|
||||
}
|
||||
res << Command{
|
||||
okmsg: 'Running net.http with -d trace_http_response works.'
|
||||
line: '${vexe} -d trace_http_response -e \'import net.http; x := http.fetch(url: "https://vpm.url4e.com/some/unknown/url")!; println(x.status_code)\''
|
||||
runcmd: .execute
|
||||
okmsg: 'Running net.http with -d trace_http_response works.'
|
||||
line: '${vexe} -d trace_http_response -e \'import net.http; x := http.fetch(url: "https://vpm.url4e.com/some/unknown/url")!; println(x.status_code)\''
|
||||
runcmd: .execute
|
||||
starts_with: '< HTTP/1.1 404 Not Found'
|
||||
contains: 'Server: nginx'
|
||||
ends_with: '404\n'
|
||||
contains: 'Server: nginx'
|
||||
ends_with: '404\n'
|
||||
}
|
||||
res << Command{
|
||||
line: '${vexe} -usecache -cg examples/hello_world.v'
|
||||
okmsg: '`v -usecache -cg` works.'
|
||||
line: '${vexe} -usecache -cg examples/hello_world.v'
|
||||
okmsg: '`v -usecache -cg` works.'
|
||||
rmfile: 'examples/hello_world'
|
||||
}
|
||||
// Note: test that a program that depends on thirdparty libraries with its
|
||||
// own #flags (tetris depends on gg, which uses sokol) can be compiled
|
||||
// with -usecache:
|
||||
res << Command{
|
||||
line: '${vexe} -usecache examples/tetris/tetris.v'
|
||||
okmsg: '`v -usecache` works.'
|
||||
line: '${vexe} -usecache examples/tetris/tetris.v'
|
||||
okmsg: '`v -usecache` works.'
|
||||
rmfile: 'examples/tetris/tetris'
|
||||
}
|
||||
$if macos || linux {
|
||||
res << Command{
|
||||
line: '${vexe} -o v.c cmd/v && cc -Werror v.c -lpthread -lm && rm -rf a.out'
|
||||
label: 'v.c should be buildable with no warnings...'
|
||||
okmsg: 'v.c can be compiled without warnings. This is good :)'
|
||||
line: '${vexe} -o v.c cmd/v && cc -Werror v.c -lpthread -lm && rm -rf a.out'
|
||||
label: 'v.c should be buildable with no warnings...'
|
||||
okmsg: 'v.c can be compiled without warnings. This is good :)'
|
||||
rmfile: 'v.c'
|
||||
}
|
||||
}
|
||||
$if linux {
|
||||
res << Command{
|
||||
line: '${vexe} vlib/v/tests/bench/bench_stbi_load.v && prlimit -v10485760 vlib/v/tests/bench/bench_stbi_load'
|
||||
okmsg: 'STBI load does not leak with GC on, when loading images multiple times (use < 10MB)'
|
||||
runcmd: .execute
|
||||
line: '${vexe} vlib/v/tests/bench/bench_stbi_load.v && prlimit -v10485760 vlib/v/tests/bench/bench_stbi_load'
|
||||
okmsg: 'STBI load does not leak with GC on, when loading images multiple times (use < 10MB)'
|
||||
runcmd: .execute
|
||||
contains: 'logo.png 1000 times.'
|
||||
rmfile: 'vlib/v/tests/bench/bench_stbi_load'
|
||||
rmfile: 'vlib/v/tests/bench/bench_stbi_load'
|
||||
}
|
||||
}
|
||||
$if !windows {
|
||||
res << Command{
|
||||
line: '${vexe} -raw-vsh-tmp-prefix tmp vlib/v/tests/script_with_no_extension'
|
||||
okmsg: 'V can crun a script, that lacks a .vsh extension'
|
||||
line: '${vexe} -raw-vsh-tmp-prefix tmp vlib/v/tests/script_with_no_extension'
|
||||
okmsg: 'V can crun a script, that lacks a .vsh extension'
|
||||
runcmd: .execute
|
||||
expect: 'Test\n'
|
||||
rmfile: 'vlib/v/tests/tmp.script_with_no_extension'
|
||||
}
|
||||
|
||||
res << Command{
|
||||
line: '${vexe} -raw-vsh-tmp-prefix tmp run vlib/v/tests/script_with_no_extension'
|
||||
okmsg: 'V can run a script, that lacks a .vsh extension'
|
||||
line: '${vexe} -raw-vsh-tmp-prefix tmp run vlib/v/tests/script_with_no_extension'
|
||||
okmsg: 'V can run a script, that lacks a .vsh extension'
|
||||
runcmd: .execute
|
||||
expect: 'Test\n'
|
||||
}
|
||||
|
|
|
@ -20,11 +20,11 @@ struct App {
|
|||
|
||||
fn new_app() App {
|
||||
return App{
|
||||
is_verbose: '-v' in os.args
|
||||
is_prod: '-prod' in os.args
|
||||
vexe: vexe
|
||||
vroot: vroot
|
||||
skip_v_self: '-skip_v_self' in os.args
|
||||
is_verbose: '-v' in os.args
|
||||
is_prod: '-prod' in os.args
|
||||
vexe: vexe
|
||||
vroot: vroot
|
||||
skip_v_self: '-skip_v_self' in os.args
|
||||
skip_current: '-skip_current' in os.args
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,12 +41,12 @@ fn (mut vt Vet) error(msg string, line int, fix FixKind) {
|
|||
line_nr: line + 1
|
||||
}
|
||||
vt.errors << VetError{
|
||||
message: msg
|
||||
message: msg
|
||||
file_path: vt.file
|
||||
pos: pos
|
||||
kind: .error
|
||||
fix: fix
|
||||
typ: .default
|
||||
pos: pos
|
||||
kind: .error
|
||||
fix: fix
|
||||
typ: .default
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,12 +55,12 @@ fn (mut vt Vet) warn(msg string, line int, fix FixKind) {
|
|||
line_nr: line + 1
|
||||
}
|
||||
mut w := VetError{
|
||||
message: msg
|
||||
message: msg
|
||||
file_path: vt.file
|
||||
pos: pos
|
||||
kind: .warning
|
||||
fix: fix
|
||||
typ: .default
|
||||
pos: pos
|
||||
kind: .warning
|
||||
fix: fix
|
||||
typ: .default
|
||||
}
|
||||
if vt.opt.is_werror {
|
||||
w.kind = .error
|
||||
|
@ -75,12 +75,12 @@ fn (mut vt Vet) notice(msg string, line int, fix FixKind) {
|
|||
line_nr: line + 1
|
||||
}
|
||||
vt.notices << VetError{
|
||||
message: msg
|
||||
message: msg
|
||||
file_path: vt.file
|
||||
pos: pos
|
||||
kind: .notice
|
||||
fix: fix
|
||||
typ: .default
|
||||
pos: pos
|
||||
kind: .notice
|
||||
fix: fix
|
||||
typ: .default
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,11 +39,12 @@ fn main() {
|
|||
vet_options := cmdline.options_after(os.args, ['vet'])
|
||||
mut vt := Vet{
|
||||
opt: Options{
|
||||
is_werror: '-W' in vet_options
|
||||
is_verbose: '-verbose' in vet_options || '-v' in vet_options
|
||||
show_warnings: '-hide-warnings' !in vet_options && '-w' !in vet_options
|
||||
use_color: '-color' in vet_options || (term_colors && '-nocolor' !in vet_options)
|
||||
is_werror: '-W' in vet_options
|
||||
is_verbose: '-verbose' in vet_options || '-v' in vet_options
|
||||
show_warnings: '-hide-warnings' !in vet_options && '-w' !in vet_options
|
||||
doc_private_fns_too: '-p' in vet_options
|
||||
use_color: '-color' in vet_options
|
||||
|| (term_colors && '-nocolor' !in vet_options)
|
||||
}
|
||||
}
|
||||
mut paths := cmdline.only_non_options(vet_options)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue