tools: implement `cgen` tag for Markdown examples in `v check-md` (#13332)
parent
b34860e39b
commit
db50e79d26
|
@ -21,6 +21,7 @@ const (
|
||||||
hide_warnings = '-hide-warnings' in os.args || '-w' in os.args
|
hide_warnings = '-hide-warnings' in os.args || '-w' in os.args
|
||||||
show_progress = os.getenv('GITHUB_JOB') == '' && '-silent' !in os.args
|
show_progress = os.getenv('GITHUB_JOB') == '' && '-silent' !in os.args
|
||||||
non_option_args = cmdline.only_non_options(os.args[2..])
|
non_option_args = cmdline.only_non_options(os.args[2..])
|
||||||
|
is_verbose = os.getenv('VERBOSE') != ''
|
||||||
)
|
)
|
||||||
|
|
||||||
struct CheckResult {
|
struct CheckResult {
|
||||||
|
@ -75,7 +76,7 @@ fn main() {
|
||||||
res += mdfile.check()
|
res += mdfile.check()
|
||||||
}
|
}
|
||||||
if res.errors == 0 && show_progress {
|
if res.errors == 0 && show_progress {
|
||||||
term.clear_previous_line()
|
clear_previous_line()
|
||||||
}
|
}
|
||||||
if res.warnings > 0 || res.errors > 0 || res.oks > 0 {
|
if res.warnings > 0 || res.errors > 0 || res.oks > 0 {
|
||||||
println('\nWarnings: $res.warnings | Errors: $res.errors | OKs: $res.oks')
|
println('\nWarnings: $res.warnings | Errors: $res.errors | OKs: $res.oks')
|
||||||
|
@ -131,9 +132,7 @@ fn eline(file_path string, lnumber int, column int, message string) string {
|
||||||
return btext('$file_path:${lnumber + 1}:${column + 1}:') + btext(rtext(' error: $message'))
|
return btext('$file_path:${lnumber + 1}:${column + 1}:') + btext(rtext(' error: $message'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const default_command = 'compile'
|
||||||
default_command = 'compile'
|
|
||||||
)
|
|
||||||
|
|
||||||
struct VCodeExample {
|
struct VCodeExample {
|
||||||
mut:
|
mut:
|
||||||
|
@ -160,7 +159,7 @@ mut:
|
||||||
|
|
||||||
fn (mut f MDFile) progress(message string) {
|
fn (mut f MDFile) progress(message string) {
|
||||||
if show_progress {
|
if show_progress {
|
||||||
term.clear_previous_line()
|
clear_previous_line()
|
||||||
println('File: ${f.path:-30s}, Lines: ${f.lines.len:5}, $message')
|
println('File: ${f.path:-30s}, Lines: ${f.lines.len:5}, $message')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -394,6 +393,7 @@ fn (mut f MDFile) debug() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cmdexecute(cmd string) int {
|
fn cmdexecute(cmd string) int {
|
||||||
|
verbose_println(cmd)
|
||||||
res := os.execute(cmd)
|
res := os.execute(cmd)
|
||||||
if res.exit_code < 0 {
|
if res.exit_code < 0 {
|
||||||
return 1
|
return 1
|
||||||
|
@ -405,6 +405,7 @@ fn cmdexecute(cmd string) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn silent_cmdexecute(cmd string) int {
|
fn silent_cmdexecute(cmd string) int {
|
||||||
|
verbose_println(cmd)
|
||||||
res := os.execute(cmd)
|
res := os.execute(cmd)
|
||||||
return res.exit_code
|
return res.exit_code
|
||||||
}
|
}
|
||||||
|
@ -426,6 +427,7 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
}
|
}
|
||||||
fname := os.base(f.path).replace('.md', '_md')
|
fname := os.base(f.path).replace('.md', '_md')
|
||||||
uid := rand.ulid()
|
uid := rand.ulid()
|
||||||
|
cfile := os.join_path(os.temp_dir(), '${uid}.c')
|
||||||
vfile := os.join_path(os.temp_dir(), 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.v')
|
vfile := os.join_path(os.temp_dir(), 'check_${fname}_example_${e.sline}__${e.eline}__${uid}.v')
|
||||||
mut should_cleanup_vfile := true
|
mut should_cleanup_vfile := true
|
||||||
// eprintln('>>> checking example $vfile ...')
|
// eprintln('>>> checking example $vfile ...')
|
||||||
|
@ -438,8 +440,7 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
fmt_res := if nofmt { 0 } else { get_fmt_exit_code(vfile, vexe) }
|
fmt_res := if nofmt { 0 } else { get_fmt_exit_code(vfile, vexe) }
|
||||||
match command {
|
match command {
|
||||||
'compile' {
|
'compile' {
|
||||||
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o x.c ${os.quoted_path(vfile)}')
|
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors ${os.quoted_path(vfile)}')
|
||||||
os.rm('x.c') or {}
|
|
||||||
if res != 0 || fmt_res != 0 {
|
if res != 0 || fmt_res != 0 {
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
eprintln(eline(f.path, e.sline, 0, 'example failed to compile'))
|
eprintln(eline(f.path, e.sline, 0, 'example failed to compile'))
|
||||||
|
@ -454,9 +455,26 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
}
|
}
|
||||||
oks++
|
oks++
|
||||||
}
|
}
|
||||||
|
'cgen' {
|
||||||
|
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}')
|
||||||
|
os.rm(cfile) or {}
|
||||||
|
if res != 0 || fmt_res != 0 {
|
||||||
|
if res != 0 {
|
||||||
|
eprintln(eline(f.path, e.sline, 0, 'example failed to generate C code'))
|
||||||
|
}
|
||||||
|
if fmt_res != 0 {
|
||||||
|
eprintln(eline(f.path, e.sline, 0, 'example is not formatted'))
|
||||||
|
}
|
||||||
|
eprintln(vcontent)
|
||||||
|
should_cleanup_vfile = false
|
||||||
|
errors++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
oks++
|
||||||
|
}
|
||||||
'globals' {
|
'globals' {
|
||||||
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -enable-globals -o x.c ${os.quoted_path(vfile)}')
|
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -enable-globals -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}')
|
||||||
os.rm('x.c') or {}
|
os.rm(cfile) or {}
|
||||||
if res != 0 || fmt_res != 0 {
|
if res != 0 || fmt_res != 0 {
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
eprintln(eline(f.path, e.sline, 0, '`example failed to compile with -enable-globals'))
|
eprintln(eline(f.path, e.sline, 0, '`example failed to compile with -enable-globals'))
|
||||||
|
@ -472,7 +490,8 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
oks++
|
oks++
|
||||||
}
|
}
|
||||||
'live' {
|
'live' {
|
||||||
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -live -o x.c ${os.quoted_path(vfile)}')
|
res := cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -live -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}')
|
||||||
|
os.rm(cfile) or {}
|
||||||
if res != 0 || fmt_res != 0 {
|
if res != 0 || fmt_res != 0 {
|
||||||
if res != 0 {
|
if res != 0 {
|
||||||
eprintln(eline(f.path, e.sline, 0, 'example failed to compile with -live'))
|
eprintln(eline(f.path, e.sline, 0, 'example failed to compile with -live'))
|
||||||
|
@ -488,8 +507,8 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
oks++
|
oks++
|
||||||
}
|
}
|
||||||
'failcompile' {
|
'failcompile' {
|
||||||
res := silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o x.c ${os.quoted_path(vfile)}')
|
res := silent_cmdexecute('${os.quoted_path(vexe)} -w -Wfatal-errors -o ${os.quoted_path(cfile)} ${os.quoted_path(vfile)}')
|
||||||
os.rm('x.c') or {}
|
os.rm(cfile) or {}
|
||||||
if res == 0 || fmt_res != 0 {
|
if res == 0 || fmt_res != 0 {
|
||||||
if res == 0 {
|
if res == 0 {
|
||||||
eprintln(eline(f.path, e.sline, 0, '`failcompile` example compiled'))
|
eprintln(eline(f.path, e.sline, 0, '`failcompile` example compiled'))
|
||||||
|
@ -533,7 +552,7 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
}
|
}
|
||||||
'nofmt' {}
|
'nofmt' {}
|
||||||
else {
|
else {
|
||||||
eprintln(eline(f.path, e.sline, 0, 'unrecognized command: "$command", use one of: wip/ignore/compile/failcompile/oksyntax/badsyntax'))
|
eprintln(eline(f.path, e.sline, 0, 'unrecognized command: "$command", use one of: wip/ignore/compile/cgen/failcompile/oksyntax/badsyntax/nofmt'))
|
||||||
should_cleanup_vfile = false
|
should_cleanup_vfile = false
|
||||||
errors++
|
errors++
|
||||||
}
|
}
|
||||||
|
@ -548,3 +567,16 @@ fn (mut f MDFile) check_examples() CheckResult {
|
||||||
oks: oks
|
oks: oks
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn verbose_println(message string) {
|
||||||
|
if is_verbose {
|
||||||
|
println(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_previous_line() {
|
||||||
|
if is_verbose {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
term.clear_previous_line()
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ Flags:
|
||||||
NB: There are several special keywords, which you can put after the code fences for v.
|
NB: There are several special keywords, which you can put after the code fences for v.
|
||||||
These are:
|
These are:
|
||||||
compile - Default, can be omitted. The example will be compiled and formatting is verified.
|
compile - Default, can be omitted. The example will be compiled and formatting is verified.
|
||||||
|
cgen - The example produces C code, which may not be compilable (when external libs are not installed). Formatting is verified.
|
||||||
live - Compile hot reload examples with the ´-live´ flag set and verify formatting.
|
live - Compile hot reload examples with the ´-live´ flag set and verify formatting.
|
||||||
ignore - Ignore the example, useful for examples that just use the syntax highlighting
|
ignore - Ignore the example, useful for examples that just use the syntax highlighting
|
||||||
failcompile - Known failing compilation. Useful for examples demonstrating compiler errors.
|
failcompile - Known failing compilation. Useful for examples demonstrating compiler errors.
|
||||||
|
|
54
doc/docs.md
54
doc/docs.md
|
@ -163,7 +163,7 @@ For more details and troubleshooting, please visit the [vab GitHub repository](h
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
NB: there are several special keywords, which you can put after the code fences for v:
|
NB: there are several special keywords, which you can put after the code fences for v:
|
||||||
compile, live, ignore, failcompile, oksyntax, badsyntax, wip, nofmt
|
compile, cgen, live, ignore, failcompile, oksyntax, badsyntax, wip, nofmt
|
||||||
For more details, do: `v check-md`
|
For more details, do: `v check-md`
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
@ -1393,7 +1393,7 @@ println(s)
|
||||||
You can check the current type of a sum type using `is` and its negated form `!is`.
|
You can check the current type of a sum type using `is` and its negated form `!is`.
|
||||||
|
|
||||||
You can do it either in an `if`:
|
You can do it either in an `if`:
|
||||||
```v
|
```v cgen
|
||||||
struct Abc {
|
struct Abc {
|
||||||
val string
|
val string
|
||||||
}
|
}
|
||||||
|
@ -5102,40 +5102,42 @@ For all supported options check the latest help:
|
||||||
|
|
||||||
#### `$if` condition
|
#### `$if` condition
|
||||||
```v
|
```v
|
||||||
// Support for multiple conditions in one branch
|
fn main() {
|
||||||
$if ios || android {
|
// Support for multiple conditions in one branch
|
||||||
|
$if ios || android {
|
||||||
println('Running on a mobile device!')
|
println('Running on a mobile device!')
|
||||||
}
|
}
|
||||||
$if linux && x64 {
|
$if linux && x64 {
|
||||||
println('64-bit Linux.')
|
println('64-bit Linux.')
|
||||||
}
|
}
|
||||||
// Usage as expression
|
// Usage as expression
|
||||||
os := $if windows { 'Windows' } $else { 'UNIX' }
|
os := $if windows { 'Windows' } $else { 'UNIX' }
|
||||||
println('Using $os')
|
println('Using $os')
|
||||||
// $else-$if branches
|
// $else-$if branches
|
||||||
$if tinyc {
|
$if tinyc {
|
||||||
println('tinyc')
|
println('tinyc')
|
||||||
} $else $if clang {
|
} $else $if clang {
|
||||||
println('clang')
|
println('clang')
|
||||||
} $else $if gcc {
|
} $else $if gcc {
|
||||||
println('gcc')
|
println('gcc')
|
||||||
} $else {
|
} $else {
|
||||||
println('different compiler')
|
println('different compiler')
|
||||||
}
|
}
|
||||||
$if test {
|
$if test {
|
||||||
println('testing')
|
println('testing')
|
||||||
}
|
}
|
||||||
// v -cg ...
|
// v -cg ...
|
||||||
$if debug {
|
$if debug {
|
||||||
println('debugging')
|
println('debugging')
|
||||||
}
|
}
|
||||||
// v -prod ...
|
// v -prod ...
|
||||||
$if prod {
|
$if prod {
|
||||||
println('production build')
|
println('production build')
|
||||||
}
|
}
|
||||||
// v -d option ...
|
// v -d option ...
|
||||||
$if option ? {
|
$if option ? {
|
||||||
println('custom option')
|
println('custom option')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ user's keyboard/mouse input.
|
||||||
|
|
||||||
## Example:
|
## Example:
|
||||||
|
|
||||||
```v
|
```v cgen
|
||||||
module main
|
module main
|
||||||
|
|
||||||
import gg
|
import gg
|
||||||
|
|
|
@ -11,7 +11,7 @@ Each `.h` file in the sokol source code is well-documented as can be seen here:
|
||||||
|
|
||||||
## Example from `@VROOTDIR/examples/sokol/sounds/simple_sin_tones.v`:
|
## Example from `@VROOTDIR/examples/sokol/sounds/simple_sin_tones.v`:
|
||||||
|
|
||||||
```v
|
```v cgen
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
import sokol.audio
|
import sokol.audio
|
||||||
|
|
Loading…
Reference in New Issue