Initial project import

This commit is contained in:
Agila Forge Importer committed 2026-07-13 15:20:32 +00:00
commit 23f2d29e32
11957 files changed
+1754577

No files matched your search

@@ -0,0 +1,148 @@
> [!NOTE]
> an important detail to remember, is that in V, the type always follows
> the identifier in declarations, i.e. you use `x int` in V in function parameters,
> and in struct declarations, not `int x`, like you would in C.
## Number types in C and V:
* A V `i8` is equivalent to C `signed char`, or `int8_t`.
* A V `i16` is equivalent to C `short`, or `int16_t`.
* A V `i32` is equivalent to C `int`, or `int32_t`.
* A V `i64` is equivalent to C `long`, or `int64_t`.
* A V `u8` is equivalent to C `unsigned char`, or `uint8_t`.
* A V `u16` is equivalent to C `unsigned short`, or `uint16_t`.
* A V `u32` is equivalent to C `unsigned int`, or `uint32_t`.
* A V `u64` is equivalent to C `unsigned long`, or `uint64_t`.
* A V `f32` is equivalent to C `float`.
* A V `f64` is equivalent to C `double`.
`char` in C is a distinct type with implementation-defined signedness, so use
V `char`, `&char`, or `charptr` when you need to match C `char`, `char*`,
or `char**`.
* A V `isize` is equivalent to C `ssize_t`.
It is a signed integer, and `isize` is guaranteed to be at least 16 bits.
It is 32 bit on 32 bit platforms, and 64 bits on 64 bit ones.
* A V `usize` is equivalent to C `size_t`.
It is an unsigned integer, and `usize` is guaranteed to be at least 16 bits.
It is 32 bit on 32 bit platforms, and 64 bits on 64 bit ones.
* A V `int` is currently equivalent to C `int`, or `int64_t`.
There are plans to make it equivalent to `isize`, so if you want to write C
library wrappers, it is better to describe your `fn C.` parameters using `i32`
instead of using `int`.
## Representing pointers in C and V:
Pointers in V are equivalent to pointers in C in usage.
One difference in their declarations, is that the order of placing the pointer
sign is swapped. For example, you use `long *` in C, which is equivalent to `&i64` in V.
If you have a C function `func_name`, that accepts a `int *`, and an `int` index,
and returns an `unsigned char`:
```c ignore
unsigned char func_name(int * p, index int);
```
... then you can represent its function signature in V like this:
```v ignore
fn C.func_name(p &int, index i32) u8
```
## Representing compound types in C and V:
A V struct is the same as a C struct, with the same field names and
types, but the order of declaring field names and their types in C structs
and V structs is different - in C you use: `short field_name;`, but in V,
that would be: `field_name i16`.
## Passing V strings to C functions:
The V string type, is currently defined like this:
```c
struct string {
u8* str;
int len;
int is_lit;
};
```
If you have a string `s` in V, and you also have a C function which
accepts `unsigned char *` in C, you can pass `s.str` to that function.
Do *not* pass `&s`, since that will be the address of the `s` struct
itself, and not the address of the characters in it (which is pointed
by `s.str`).
## Passing V dynamic array elements to C functions:
All V array types currently share the same C type, currently defined like this:
```c
struct array {
void * data;
// For arrays, the following `offset` field is 0.
// For slices, the `offset` field contains the offset (in elements) from
// the start of the original array.
int offset;
int len;
int cap;
int flags;
int element_size;
};
```
If you want to pass a pointer to the elements of a V array `a`, to a C function,
use `a.data`. NOTE: do *not* use `&a` for that purpose. That will result in the address
of the `array` itself, getting passed to the C function, and *not* the address of the
elements of the V array.
## Passing V fixed array elements to C functions:
Unlike dynamic arrays, fixed arrays are the same in both V and C.
The address of the first element of the V fixed array of integers `fa` with
type `[5]i32`, is `&fa[0]` . That address can be directly used a parameter to
C functions, that accept `int * p` or `int arr[]` parameters.
## Functions in V and C:
The type of a V function, with no receiver, is equivalent to a C function,
given that the types of the parameters are equivalent.
When a V function returns more than one value, the C function returns a struct.
For example, these functions have equivalent types:
```v ignore
fn v_function(a u64, b i8) (i32, f32)
```
```c ignore
struct { int i; float f; } c_function(unsigned long a, signed char b);
````
A pointer to a V function is equivalent to a pointer to a C function, when the
functions have equivalent types.
## Other V types, that are currently not supported/documented for use with C:
Other V types like interface, thread, chan, and map types are represented
as C structs, but they are deliberately not yet completely documented for the
purposes of C interoperability, since their implementations can still change.
C struct types containing bitfields, currently have no corresponding V types.
C++ class types have no corresponding V types.
## Memory allocation in V and C
Keep in mind, that V uses the Boehm's garbage collector by default. You can pass
a pointer to allocated memory from C to V, just remember that the responsibility
of freeing the pointer will remain with the C side, and if the C side frees the
pointer while the V side still has a copy, your program will fail.
When passing a pointer from V to C, the V function must retain a visible copy
of it in some V variable. Otherwise the V garbage collector may free the
corresponding memory, while the C function is still using it. You can use the
attribute `@[keep_args_alive]` to tag your `fn C.` declarations, that accept
pointers, to keep them from being freed, while the call to your `C.fname()`
function has not returned.
For more details, see also this
[test for keep_args_alive](vlib/v/slow_tests/keep_args_alive_test.c.v) .
+94
View File
@@ -0,0 +1,94 @@
# CodeLite Setup
CodeLite works well with V when you open the code as a
[File System Workspace](https://docs.codelite.org/workspaces/file_system/)
and define custom build targets with
[CodeLite macros](https://docs.codelite.org/settings/macros/).
This guide uses POSIX shell commands, which match Linux and macOS. On Windows,
use `.exe` outputs and replace `rm -f` with `del`.
## Prerequisites
- Put `v` on your `PATH`. If it is not on your `PATH`, replace `v` below
with the absolute path to your V compiler.
- Create a CodeLite workspace from your existing source tree:
1. Open `File` -> `New` -> `New workspace`
2. Choose `File System Workspace`
3. Select the folder containing your V sources
Open the workspace settings by right-clicking the top-level folder and choosing
`Settings...`.
## General Settings
Set these fields first:
- `Tool chain`: `gcc` or `clang`
- `File extensions`: add `v`, `vsh`, and `vv`
CodeLite uses the selected tool chain mainly to parse build output, so any
GNU-like tool chain is fine here.
For single-file programs, use:
- `Executable`: `$(CurrentFilePath)/$(CurrentFileName)`
- `Working directory`: `$(CurrentFilePath)`
For a project rooted at the workspace folder, use:
- `Executable`: `$(WorkspacePath)/$(WorkspaceName)`
- `Working directory`: `$(WorkspacePath)`
## Build Targets
The default `build` and `clean` targets can not be removed. Add `run` and
`test` targets if you want them in the `Build` menu.
### Build the current file
This is the simplest setup for scripts, examples, and small programs:
- `build`:
`v -g -o "$(CurrentFilePath)/$(CurrentFileName)" "$(CurrentFileFullPath)"`
- `clean`: `rm -f "$(CurrentFilePath)/$(CurrentFileName)"`
- `run`: `v run "$(CurrentFileFullPath)"`
- `test`: `v test "$(CurrentFileFullPath)"`
### Build the whole workspace
If the workspace root is a V project with `v.mod`, or the workspace folder is
your app entry point, use:
- `build`: `v -g -o "$(WorkspacePath)/$(WorkspaceName)" "$(WorkspacePath)"`
- `clean`: `rm -f "$(WorkspacePath)/$(WorkspaceName)"`
If your app starts from a specific file such as `src/main.v`, replace
`"$(WorkspacePath)"` with that file path in the `build` target.
## Running and Debugging
- Press `F7` to run the `build` target.
- Use `Run` or `Debug` after `Executable` points to the file produced by the
build target.
- Keep `-g` in the build command so `gdb` or `lldb` can show V source
locations.
## Better Compiler Errors in the IDE
If CodeLite opens the wrong file from compiler errors, add this workspace
environment variable:
- `VERROR_PATHS=absolute`
That makes `v` print absolute file paths, which is often better for IDE
launchers.
## Formatting and Language Features
For manual formatting, or for a formatter command inside CodeLite, use:
- `v fmt -w "$(CurrentFileFullPath)"`
For completion, go-to-definition, hover information, and related IDE features,
use [v-analyzer](https://github.com/vlang/v-analyzer) alongside CodeLite.
+9185
View File
File diff suppressed because it is too large. Load diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

+217
View File
@@ -0,0 +1,217 @@
# Ownership
V has an optional ownership system inspired by Rust that tracks owned values and prevents
use-after-move bugs at compile time. It is currently focused on strings and is enabled
with the `-ownership` flag.
## Quick start
```v okfmt
fn main() {
s1 := 'hello'.to_owned()
s2 := s1 // s1 is moved to s2
println(s1) // error: use of moved value: `s1`
}
```
Compile with ownership checking:
```
v2 -ownership -o out main.v
```
## Creating owned values
Call `.to_owned()` on a string to create an owned copy. Only strings created with
`.to_owned()` participate in ownership tracking — regular string literals and primitive
types (int, f64, bool, ...) are unaffected.
```v okfmt
s := 'hello'.to_owned() // s is owned
t := 'world' // t is a normal string, no ownership tracking
```
## Move semantics
Assigning an owned value to another variable **moves** it. The original variable
becomes unusable:
```v okfmt
s1 := 'hello'.to_owned()
s2 := s1 // move
println(s1) // error: use of moved value: `s1`
```
Passing an owned value to a function also moves it:
```v okfmt
fn takes_ownership(s string) {
println(s)
}
fn main() {
s := 'hello'.to_owned()
takes_ownership(s)
println(s) // error: use of moved value: `s`
}
```
### Preventing moves with `.clone()`
Use `.clone()` to make an independent copy instead of moving:
```v okfmt
s1 := 'hello'.to_owned()
s2 := s1.clone() // s1 is NOT moved
println(s1) // ok
println(s2) // ok
```
```v okfmt
takes_ownership(s.clone()) // s is NOT moved
println(s) // ok
```
## Borrowing
Pass `&variable` to borrow without moving. The original stays usable:
```v okfmt
fn calculate_length(s &string) int {
return s.len
}
fn main() {
s := 'hello'.to_owned()
len := calculate_length(&s)
println(s) // ok — s was borrowed, not moved
}
```
### Explicit lifetimes
Ownership mode also supports explicit named lifetimes with `^name`.
Use `&^a T` for a borrowed reference with an explicit lifetime and `[^a]`
in generic parameter and argument lists:
```v ignore
struct Ignore {}
struct IgnoreMatch[^a] {}
fn matched_dir_entry[^a](self &^a Ignore) IgnoreMatch[^a] {
return IgnoreMatch[^a]{}
}
```
`^` is used instead of Rust's `'` because `'` is already used for string and
character literals in V.
Multiple immutable borrows are allowed:
```v okfmt
s := 'hello'.to_owned()
r1 := &s
r2 := &s // ok
```
Mutable borrows via `mut` parameters work too — the variable is usable after the
call returns:
```v ignore
fn append_world(mut s string) {
s = s + ' world'
}
fn main() {
mut s := 'hello'.to_owned()
append_world(mut s)
println(s) // ok — prints "hello world"
}
```
### Borrow restrictions
A borrowed variable cannot be moved or reassigned while the borrow is active:
```v okfmt
s := 'hello'.to_owned()
r := &s
s2 := s // error: cannot move `s` because it is borrowed
```
```v okfmt
mut s := 'hello'.to_owned()
r := &s
s = 'world'.to_owned() // error: cannot assign to `s` because it is borrowed
```
## Return value ownership
Functions that create and return owned values transfer ownership to the caller:
```v okfmt
fn gives_ownership() string {
return 'hello'.to_owned()
}
fn main() {
s1 := gives_ownership() // s1 is owned
s2 := s1 // move
println(s1) // error: use of moved value
}
```
Functions that return a parameter pass ownership through:
```v okfmt
fn takes_and_gives_back(s string) string {
return s
}
fn main() {
s1 := 'hello'.to_owned()
s2 := takes_and_gives_back(s1) // s1 moved in, ownership comes back as s2
println(s1) // error: s1 was moved
println(s2) // ok
}
```
## Full example
From the Rust book, translated to V:
```v okfmt
fn gives_ownership() string {
s := 'hello'.to_owned()
return s
}
fn takes_and_gives_back(a_string string) string {
return a_string
}
fn main() {
s1 := gives_ownership()
s2 := 'hello'.to_owned()
s3 := takes_and_gives_back(s2)
println(s1) // ok
println(s3) // ok
}
```
## Enabling ownership checking
Ownership checking is compiled into a separate `v2_ownership` binary using V's
compile-time defines so there is zero overhead in the normal `v2` binary.
```
v2 -ownership file.v # check and compile
```
To build the ownership-enabled compiler manually:
```
v -d ownership -o v2_ownership cmd/v2/v2.v
```
@@ -0,0 +1,133 @@
Packaging V
=============
Thank you for supporting V and its users, and for creating, *and maintaining* a package for it.
V is still changing, and installing it from source, is still the *recommended way*, to
distribute it to most V users.
However, we understand that sooner or later people will want to adapt the
upstream source to their favorite distro/platform, and that usually involves preparing a package
that will be installed and updated (using a standardized package manager) just like all other
programs in the distribution.
This document is for the brave people that want to prepare and
*maintain* such a package.
Good luck.
Details
=============
Preparing a package of the current version of V for distribution, has some peculiarities
that must be understood, and taken into account, for the best experience of the users of
your package, for your sanity, and for easier troubleshooting of problems when they happen.
1) V builds many of its commands on demand, to save both time and space. The source of the
entry points of those commands is stored in the folder cmd/tools/ . If you are preparing a
prebuilt V package, that needs to ensure that the final package after installation will be
read only, that will be a problem, since V will try to write to its cmd/tools/ folder.
To prevent that, you need to build *all* the commands/executables in that folder *ahead of time*.
This can be done by the command `v build-tools`.
2) Tell V to not try to recompile its tools anymore. To do that, V supports checking for the
presence of a file named `cmd/tools/.disable_autorecompilation` (that file is missing by default
in the cloned version of V).
Note: the content of this file does not matter, *only its presence does*.
3) V has a tool/command, that enables rapid updating from the latest master branch in its main
repository. That tool is `v up`. Most distros however, have the policy of not allowing packages
to make modifications to themselves. Instead, they require the user to use their package manager,
provided by the distro/platform.
To facilitate that, it is usually best for all involved if you, as a package maintainer, remove
or replace cmd/tools/vup.v, with a short v program, that advises the final V user to use the
package manager tool, or to use a V installed from source instead.
4) Another V feature/command that can interfere with read only packaging is `v self`. We
recommend that you disable this command as well, by replacing cmd/tools/vself.v with a small
V program that informs the user that `v self` is not recommended when used with a packaged
version of V, and then advises the user to install V from source if he wants to use `v self`.
5) The V source repo contains sizable folders like `.git/` and `thirdparty/tcc/.git/` which will
not be needed by users of packages (they are not useful if `v up` is disabled,
as recommended previously). Some other files, such as `Makefile`, `makev.bat`, and `GNUmakefile`
will not be used either, so they can also be safely removed.
Depending on how stripped you want your package, you can remove the examples/ folder as well.
It is usually good to have examples, but they could be in a separate package.
If a user attempts to compile the examples in that folder, it
will not work in a read-only package (because the executables are put right next to the
source `.v` files by default, unless `-o path_to_executable_name` is used).
6) Location of vlib/ . V expects, that its vlib/ folder, will be located right next to its
executable, and that is currently hard to customize. It will be changed, if there is enough
interest from package maintainers, expressed on the V issue tracker:
https://github.com/vlang/v/issues
*However, you can* leave the executable in say /opt/vlang/v, with vlib/ in /opt/vlang/vlib/ ,
then put a symlink from `/opt/vlang/v` to whatever folder that is on the user's PATH on your
distro, i.e.: `sudo ln -s /opt/vlang/v /usr/bin/v` or `sudo ln -s /opt/vlang/v /bin/v` .
7) Location of the V executable can be controlled by setting the env variable VEXE.
It defaults to the absolute path of the V executable.
8) Location of the modules folder for `v install` can be controlled by setting the env variable
named `VMODULES`. By default, modules are installed to `~/.vmodules`,
(`C:\Users\<user id>\.vmodules` on Windows).
9) Location of the folder used by V for its temporary files can be controlled by setting the env
variable `VTMP`. By default, the system TEMP folder is used.
10) Setting additional V flags for each compilation can be done by setting the env variable
`VFLAGS`.
Note: points 7, 8, 9, 10 above, allow you to create a small launcher shell script, named `v`,
that sets those variables dynamically, according to the current user. You can then put
*this shell script* inside your package bin folder, i.e. inside /usr/bin/v, or /bin/v etc,
*instead of* the main V executable, or a symlink to it.
Example script to prepare the V source folder for packaging:
-----------------------------------------------------------
Combining all of the above, here is a small script, that can be used as a base for your packaging
efforts:
```sh
echo "println('use your package manager to update V," > cmd/tools/vup.v
echo "or if you want more recent V versions, just clone V from source," >> cmd/tools/vup.v
echo "see https://github.com/vlang/v#installing-v-from-source')" >> cmd/tools/vup.v
echo "println('v self is disabled for packaged versions of V." > cmd/tools/vself.v
echo "Use your package manager, to update your V package instead." >> cmd/tools/vself.v
echo "Alternatively, if you do want a more recent V version, just clone V from source," >> cmd/tools/vself.v
echo "then follow the instructions here: https://github.com/vlang/v#installing-v-from-source')" >> cmd/tools/vself.v
v -prod -o v cmd/v ## build V itself with -prod
./v -prod build-tools ## build all tools with -prod too
touch ./cmd/tools/.disable_autorecompilation ## tell V to not try to recompile any tool anymore
### Cleanup folders that would not be needed inside a package,
### that is distributed separately from the V source repository:
rm -rf .git/
rm -rf thirdparty/tcc/.git/
```
Example `v` script for your bin folder:
--------------------------------------------------
```sh
#!/usr/bin/env bash
export VEXE="/opt/vlang/v"
export VFLAGS="-cc /usr/bin/custom_cc"
export VCACHE="/var/cache/custom_vcache_folder" ## ~/.vmodules/cache by default
export VTMP="/var/cache/custom_tmp"
export VMODULES="$HOME/.vmodules"
/opt/vlang/v $@
```
Note: do not forget to also do this in your post install script: `chmod +x /usr/bin/v`
+208
View File
@@ -0,0 +1,208 @@
# V Work In Progress
***This document describes features that are not implemented, yet.
Please refer to [docs.md](https://github.com/vlang/v/blob/master/doc/docs.md)
for the current state of V***
## Table of Contents
* [Concurrency](#concurrency)
* [Variable Declarations](#variable-declarations)
* [Strengths](#strengths)
* [Weaknesses](#weaknesses)
* [Compatibility](#compatibility)
* [Automatic Lock](#automatic-lock)
* [Channels](#channels)
## Concurrency
### Variable Declarations
Objects that are supposed to be used to exchange data between
coroutines have to be declared with special care. Exactly one of the following
4 kinds of declaration has to be chosen:
```v ignore
a := ...
mut b := ...
shared c := ...
atomic d := ...
```
- `a` is declared as *constant* that can be passed to
other coroutines and read without limitations. However
it cannot be changed.
- `b` can be accessed reading and writing but only from one
coroutine. That coroutine *owns* the object. A `mut` variable can
be passed to another coroutine (as receiver or function argument in
the `go` statement or via a channel) but then ownership is passed,
too, and only the other coroutine can access the object.<sup>1</sup>
- `c` can be passed to coroutines an accessed
*concurrently*.<sup>2</sup> In order to avoid data races it has to
be locked before access can occur and unlocked to allow access to
other coroutines. This is done by one the following block structures:
```v ignore
lock c {
// read, modify, write c
...
}
```
```v ignore
rlock c {
// read c
...
}
```
Several variables may be specified: `lock x, y, z { ... }`.
They are unlocked in the opposite order.
- `d` can be passed to coroutines and accessed *concurrently*,
too.<sup>3</sup> No lock is needed in this case, however
`atomic` variables can only be 32/64 bit integers (or pointers)
and access is limited to a small set of predefined idioms that have
native hardware support.
To help making the correct decision the following table summarizes the
different capabilities:
| | *default* | `mut` | `shared` | `atomic` |
|:-------------------------|:---------:|:-----:|:--------:|:--------:|
| write access | | + | + | + |
| concurrent access | + | | + | + |
| performance | ++ | ++ | | + |
| sophisticated operations | + | + | + | |
| structured data types | + | + | + | |
### Strengths
**default**
- very fast
- unlimited access from different coroutines
- easy to handle
**`mut`**
- very fast
- easy to handle
**`shared`**
- concurrent access from different coroutines
- data type may be complex structure
- sophisticated access possible (several statements within one `lock`
block)
**`atomic`**
- concurrent access from different coroutines
- reasonably fast
### Weaknesses
**default**
- read only
**`mut`**
- access only from one coroutine at a time
**`shared`**
- lock/unlock are slow
- moderately difficult to handle (needs `lock` block)
**`atomic`**
- limited to single (max. 64 bit) integers (and pointers)
- only a small set of predefined operations possible
- very difficult to handle correctly
<sup>1</sup> The owning coroutine will also free the memory space used
for the object when it is no longer needed.
<sup>2</sup> For `shared` objects the compiler adds code for reference
counting. Once the counter reaches 0 the object is automatically freed.
<sup>3</sup> Since an `atomic` variable is only a few bytes in size
allocation would be an unnecessary overhead. Instead the compiler
creates a global.
### Compatibility
Outside of `lock`/`rlock` blocks function arguments must in general
match - with the familiar exception that objects declared `mut` can be
used to call functions expecting immutable arguments:
```v ignore
fn f(x St) {...}
fn g(mut x St) {...}
fn h(shared x St) {...}
fn i(atomic x u64) {...}
a := St{...}
f(a)
mut b := St{...}
f(b)
go g(mut b)
// `b` should not be accessed here anymore
shared c := St{...}
h(shared c)
atomic d &u64
i(atomic d)
```
Inside a `lock c {...}` block `c` behaves like a `mut`,
inside an `rlock c {...}` block like an immutable:
```v ignore
shared c := St{...}
lock c {
g(mut c)
f(c)
// call to h() not allowed inside `lock` block
// since h() will lock `c` itself
}
rlock c {
f(c)
// call to g() or h() not allowed
}
```
### Automatic Lock
In general the compiler will generate an error message when a `shared`
object is accessed outside of any corresponding `lock`/`rlock`
block. However in simple and obvious cases the necessary lock/unlock
can be generated automatically for `array`/`map` operations:
```v ignore
shared a := []int{cap: 5}
go h2(shared a)
a << 3
// keep in mind that `h2()` could change `a` between these statements
a << 4
x := a[1] // not necessarily `4`
shared b := map[string]int{}
go h3(shared b)
b['apple'] = 3
c['plume'] = 7
y := b['apple'] // not necessarily `3`
// iteration over elements
for k, v in b {
// concurrently changed k/v pairs may or may not be included
}
```
This is handy, but since other coroutines might access the `array`/`map`
concurrently between the automatically locked statements, the results
are sometimes surprising. Each statement should be seen as a single
transaction that is unrelated to the previous or following
statement. Therefore - but also for performance reasons - it's often
better to group consecutive coherent statements in an explicit `lock` block.
### Channels
+160
View File
@@ -0,0 +1,160 @@
# Visual Studio Code Setup
## Table of Contents
* [V language support](#v-language-support)
* [Visual Debugging](#visual-debugging)
## V language support
The [V VS Code Extension](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
provides V language support for Visual Studio Code.
![Screenshot Code with activated extension](https://github.com/vlang/vscode-vlang/raw/HEAD/images/demo.png)
**Features:**
* Syntax Highlighting.
* Code Snippets for quick coding.
* Format code on file save as well as format manually (using v fmt).
* Linter (Workspace files only).
[more](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang)
**Hint:** This extension will not add the V compiler! Information on how to
[install V compiler](https://github.com/vlang/v/blob/master/doc/docs.md#install-from-source)
on your operating system.
### Setup Extension
Install [V VS Code Extension](https://marketplace.visualstudio.com/items?itemName=vlanguage.vscode-vlang).
## Visual Debugging
![screenshot visual debugger](https://github.com/vlang/v/blob/master/doc/img/vscode-debugger.png?raw=true)
The [C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
for Visual Studio Code provides visual conditional debugging.
**Features:**
* Conditional breakpoints
* Function breakpoints
* Expression evaluation
* Change Values
[more Features & Documentation](https://code.visualstudio.com/docs/cpp/cpp-debug)
**Hint:** Not all types (e.g. Array) in V currently create the required
[DWARF](https://en.wikipedia.org/wiki/DWARF) information to show and
edit the variable.
### Setup Debugging
#### Step1: Configure the launch.json file
1. Install the
[C/C++ Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools)
2. Open `RUN AND DEBUG` panel (Debug Icon in left panel).
3. Click on `Show` all automatic debug configurations.
4. Select `Add config`.
5. Select environment `C++ (GDB/LLDB)`.
6. Change the line `"program": "Enter the program name, e.g. \"${workspaceFolder}/a.out\"",`
to point to your compiled application e.g. `"program": "${workspaceFolder}/hello",`
or a more flexible one `"program": "${fileDirname}/${fileBasenameNoExtension}",`
when you want to debug the current opened file.
This will add a block to your `.workspace` file,
or create the file `.vscode/launch.json`:
```json
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit:
// https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(lldb) Start",
"type": "cppdbg",
"request": "launch",
"program": "Enter the program name, e.g. \"${workspaceFolder}/a.out\"",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "lldb",
"preLaunchTask": "build"
}
]
}
```
**Optional:** use `"program": "${fileDirname}/${fileBasenameNoExtension}"` to debug
any current open source file with an existing binary with the same name but without any extension.
#### Step2: Configure the tasks.json file
Generally, you can manually compile the application with: `v -b c -g hello.v -o hello`,
or for short: `v -g hello.v`, and then call the debugger.
The `-g` option will add the needed debugging information.
You can find more debugging options in the [docs](docs.md#debugging).
VS Code provides a hook called `preLaunchTask`, which can be used to compile
the application automatically every time you call the debugger.
[preLaunchTask](https://code.visualstudio.com/docs/editor/debugging#_launchjson-attributes) launches
a task before the start of a debug session, set this attribute to the label of a task specified
in [task.json](https://code.visualstudio.com/docs/editor/tasks) (in the workspace's .vscode folder).
Or, this can be set to `${defaultBuildTask}`, to use your default build task.
As explained, the `"preLaunchTask": "build"` needs to work with a `.vscode/tasks.json`
with a label named `build`.
```json
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "v",
"args": [
"-g", // add more compiler options here if necessary
"${relativeFile}" // or modify it according to your requirements
],
"group": "build",
"presentation": {
"reveal": "never"
},
"problemMatcher": {
"owner": "v",
"fileLocation": ["relative", "${workspaceFolder}"],
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
}
]
}
```
### Usage
To allow your compiled application to be debugged.
The application needs to include additional debugging information
([DWARF](https://en.wikipedia.org/wiki/DWARF)).
1. Open your source code and set the required break points
2. Click on the Debug Icon in the left Icon panel and click
`> (lldb) Start`, or use `F5` to launch your application in debug mode.
For all options look at the official
[C/C++ Extension documentation](https://code.visualstudio.com/docs/cpp/cpp-debug).