Compare commits

...

323 Commits

Author SHA1 Message Date
Jef Roosens 9a0f499506
ci: Added PKGBUILD & workflow for deploying Arch packages
ci/woodpecker/push/vc Pipeline was successful Details
ci/woodpecker/push/docker Pipeline was successful Details
ci/woodpecker/push/arch Pipeline was successful Details
2022-05-17 12:36:35 +02:00
Jef Roosens b21fa77baf
ci: Added docker workflow & Dockerfile 2022-05-17 12:27:08 +02:00
Delyan Angelov da42f0d42b
ci: add an early step 'All code is formatted' to more workflows. 2022-05-17 13:14:08 +03:00
Delyan Angelov 3fc4459485
ci: ignore orm_joined_tables_select_test.v on tasks, that do not have sqlite installed 2022-05-17 12:53:07 +03:00
yuyi 020845f6c3
cgen: fix alias of array that has builtin method (#14432) 2022-05-17 12:26:26 +03:00
yuyi d7b1e57186
v.builder: improve builder error messages (fix #14386) (#14421) 2022-05-17 12:12:20 +03:00
yuyi 60e817ff32
cgen: minor optimization in index_of_array/map() (#14429) 2022-05-17 12:08:44 +03:00
yuyi d6aa85d059
parser: fix panic for parse invalid map type (#14431) 2022-05-17 12:05:10 +03:00
playX 7c6eaa8204
checker: allow to use [n]anyptr as [n]otherptr in check_types (c2v fix) (#14433) 2022-05-17 11:55:04 +03:00
Delyan Angelov 78ab3296c9
checker: fix orm bug, when a joined table field context replaced the original table field context 2022-05-17 11:45:17 +03:00
WoodyAtHome 02c8a6057c
builtin.string: new fn (s string) is_ascii() bool (#14418) 2022-05-17 08:01:03 +03:00
Alexander Medvednikov d10f83ce15 cgen: fix c2v struct eq 2022-05-17 03:39:48 +03:00
playX bc397bb0e1
checker: c2v array fix (#14426) 2022-05-17 00:08:41 +03:00
Delyan Angelov 32dd801201
checker: apply fix for ui suggested by spaceface 2022-05-16 21:33:02 +03:00
Delyan Angelov 9cb8bb2968
Revert "Revert "checker: allow using methods as vars when expecting a ctx arg (#14414)""
This reverts commit e5c7fe3006.
2022-05-16 21:29:47 +03:00
yuyi c624de8523
cgen: fix struct field array index error (#14417) 2022-05-16 19:37:39 +03:00
Delyan Angelov e5c7fe3006
Revert "checker: allow using methods as vars when expecting a ctx arg (#14414)"
This reverts commit 36bec823c2.
2022-05-16 14:19:33 +03:00
Delyan Angelov 39874ae168
clipboard: fix `v -gc boehm run x.v`, where x.v does c.paste() (fix #14281) 2022-05-16 12:54:30 +03:00
yuyi d59f4e9479
ast, cgen: fix generic method with variadic generic argument (#14404) 2022-05-16 12:26:38 +03:00
Larpon ef6225c542
vvet: fix false positive, add test (#14403) 2022-05-16 12:24:21 +03:00
yuyi 0ab4133128
cgen: minor cleanup in struct_init() (#14405) 2022-05-16 12:22:51 +03:00
spaceface 36bec823c2
checker: allow using methods as vars when expecting a ctx arg (#14414) 2022-05-16 12:05:08 +03:00
WoodyAtHome c2b763655d
net.smtp: handle UTF-8 subjects according to RFC 1342 (#14410) 2022-05-16 11:09:36 +03:00
Delyan Angelov 1cf683d482
checker: add a suggestion for misspelled mod.const_name + a test 2022-05-16 10:29:58 +03:00
Delyan Angelov b4c529066a
tests: simplify cmd/tools/modules/testing/common.v 2022-05-16 10:29:57 +03:00
Ben cbb24d34c9
os: fix is_abs_path function for Windows systems (#14397) 2022-05-16 09:59:37 +03:00
yuyi 7fe3ef9a6e
fmt: fix fmt error of anon fn with if expr (fix #14393) (#14413) 2022-05-16 09:48:21 +03:00
Larpon 5068b8b293
ftp: document all public methods (#14408) 2022-05-16 08:52:12 +03:00
Jah-On 02e026e298
clipboard: add `[heap]` tag to the Clipboard structs (#14412) 2022-05-16 08:45:40 +03:00
WoodyAtHome eeff02a8ee
net.openssl: read doesn't block infinitely (#14406) 2022-05-16 08:44:34 +03:00
spaceface c01a8a1737
checker,gen: allow using methods as function pointers (#14407) 2022-05-15 18:28:37 +03:00
Delyan Angelov c2bc9f4960
sync: only run channel_select_test.v when VTEST_RUN_FLAKY=1 2022-05-15 12:43:04 +03:00
crthpl e4065bd57b
checker,cgen: fix if expressions in lock expression (#14384) 2022-05-15 12:31:07 +03:00
David 'Epper' Marshall c28051020a
time: fix calculate_date_from_offset (#14399) 2022-05-15 10:55:24 +03:00
Delyan Angelov b50f7fdc71
ci: simplify ci_sanitized.yml again; use `v.exe fmt -verify vlib/builtin` for windows/msvc instead of `v test-cleancode` 2022-05-15 10:54:31 +03:00
Delyan Angelov c70e18ea8f
ci: add a skip list in compiler_test.v (for tmpl_parse_html.vv) 2022-05-15 10:23:13 +03:00
Delyan Angelov 3a09ccc80a
ci: restore .github/workflows/ to its state at cee7856, when all checks were done 2022-05-15 10:23:12 +03:00
Larpon dd6629e932
examples: fix 2048 scaling on Android (#14380) 2022-05-15 09:14:18 +03:00
David 'Epper' Marshall 8d141878ce
math: cbrt fix (#14395) 2022-05-14 21:06:38 +03:00
Delyan Angelov 67963e0ff2
ci: further cleanup of ci_sanitized.yml 2022-05-14 20:34:01 +03:00
Delyan Angelov 1225a865a3
ci: simplify ci_sanitized.yml 2022-05-14 20:29:56 +03:00
yuyi fe9f97074b
cgen: fix appending struct to interface array (#14388) 2022-05-14 17:49:42 +03:00
Alexander Medvednikov 3adad32355 tmpl: fix a test 2022-05-14 17:48:50 +03:00
Alexander Medvednikov b42c824cdb vweb: simplify @foo by removing V_TEMPLATE rule 2022-05-14 17:46:30 +03:00
Daniel Däschle f0d46413d9
ci: require code to be formatted before everything else (minimise CI queue length) (#14396) 2022-05-14 15:38:15 +03:00
JalonSolov b3e80a3100
examples: add missing v.mod file (#14392) 2022-05-14 14:48:42 +03:00
j. redhead 441637eeb4
checker: fix optionals in infix expression check (fix #14354) (#14390) 2022-05-14 00:54:49 +03:00
Delyan Angelov cee7856c0f
ci: add a quick `v test-cleancode` check, before more costlier tasks 2022-05-13 12:24:11 +03:00
Delyan Angelov 714ce4e7fc
ci: fix .out regression after d407a64 2022-05-13 11:18:17 +03:00
Delyan Angelov c1bafe7a5a
ci: extract v_apps_and_modules_compile.yml 2022-05-13 11:02:24 +03:00
playX 6ec4185017
checker: allow to pass alias to array as a pointer (c2v) (#14389) 2022-05-13 10:17:28 +03:00
Daniel Däschle d407a6449d
parser: fix dollar (closes #14292) (#14378) 2022-05-13 08:30:10 +03:00
Delyan Angelov ed12a5c84c
math.big: reduce memory usage of Integer.str() (free intermediary Integers), optimise some operations using `[direct_array_access]` (#14353) 2022-05-13 08:21:34 +03:00
yuyi 3c95504a35
checker, cgen: fix generic fn with array and fixed array arguments (#14385) 2022-05-13 06:57:48 +03:00
Daniel Däschle d679146a80
fmt: remove space in front of ? and ! (#14366) 2022-05-13 06:56:21 +03:00
Delyan Angelov df029da942
Revert "ci: run `code-formatting` job before everything else (try 2) (#14379)"
This reverts commit 0972e67f72.
2022-05-12 23:29:37 +03:00
Daniel Däschle 0972e67f72
ci: run `code-formatting` job before everything else (try 2) (#14379) 2022-05-12 21:58:11 +03:00
Delyan Angelov 8ef9dc6247
ci: run `v fmt -w vlib/v/checker/fn.v` (fix CI regression after 4952967) 2022-05-12 21:24:12 +03:00
Delyan Angelov 668d1b04d2
parser: make script mode errors more informative, when a top level declaration is encountered, after script mode had already started 2022-05-12 21:14:00 +03:00
Hunam 20139ad756
checker: fix typo (#14368) 2022-05-12 12:23:32 +03:00
playX 4952967366
checker: alias C2V fix (#14377) 2022-05-12 12:19:31 +03:00
yuyi f48f7014f0
checker: check error for generic sumtype types (#14374) 2022-05-12 11:57:57 +03:00
penguindark e93a8766e5
regex: fix #14370, last IST not managed in advance tests (#14372) 2022-05-12 11:49:57 +03:00
Delyan Angelov b7ca4c1668
checker: fix a compiler panic on `fntest()?(&int,&int){return test()?}` 2022-05-12 11:36:32 +03:00
yuyi 8830af5c89
rand: minor cleanup in choose() (#14376) 2022-05-12 11:20:38 +03:00
yuyi 5bc4fea9e0
checker: check error for cast function to string (#14375) 2022-05-12 10:04:38 +03:00
CC 901b8f0c24
builtin: add a map.clear() method (#14373) 2022-05-12 09:43:01 +03:00
spaceface 49382f1f43
gen: make the closure implementation more performant (#14352) 2022-05-12 00:05:14 +03:00
Emily Hudson c19b037880
net: select with deadlines (#14369) 2022-05-12 00:03:48 +03:00
yuyi cd4fa041ff
checker: check generic sumtype declare error (#14367) 2022-05-11 17:39:58 +03:00
Larpon 34a252ef84
os: add `raw_execute` on Windows (#14363) 2022-05-11 16:56:03 +03:00
David 'Epper' Marshall 26b81d68b5
time: update doc comments (#14359) 2022-05-11 16:55:19 +03:00
Larpon 0ec1c8d9f0
szip: expose zip_folder (#14356) 2022-05-11 16:48:41 +03:00
yuyi 3afc7c4c6d
parser: check error for generic struct parameter (#14362) 2022-05-11 13:24:54 +03:00
Delyan Angelov cf536b848b
Revert "strings: reduce time spent in Builder.writeln (very frequently called)"
This reverts commit b53b1cc7cb.
2022-05-11 09:19:37 +03:00
yuyi 8f765ed5f1
checker: minor cleanup and speedups in fn_call() (#14343) 2022-05-10 16:41:47 +03:00
yuyi 5697d4375b
cgen: fix error for printing aliases of multi fixed array (#14348) 2022-05-10 14:03:18 +03:00
yuyi 606d8cfaca
checker: check error for returning aliases of fixed array (#14349) 2022-05-10 14:01:55 +03:00
Isaiah 9e09b709e3
net.http: fix crash on Windows when using Boehm GC (#14351) 2022-05-10 14:00:55 +03:00
yuyi 940c78bdfd
checker: minor cleanup in method_call() (#14342) 2022-05-09 18:01:44 +03:00
Subhomoy Haldar 79f8a3c796
rand: update README.md (#14341)
* update README for rand module

* use concrete values

* make sure code works
2022-05-09 17:59:20 +03:00
StunxFS d24dce8eb3
parser,checker: support `$compile_error('message')` and `$compile_warn('message')` (#14320) 2022-05-09 08:18:26 +03:00
Dialga 4400f9891e
szip: fix extracting dot folders (#13387) 2022-05-09 07:45:36 +03:00
yuyi 8519996201
checker: fix error for match sumtype that referenced before (#14338) 2022-05-09 07:32:51 +03:00
Merlin Diavova 106487d62f
pg: resolve PG string datetime values to V time.Time ones (#14336)
Co-authored-by: Merlin Diavova <md@merlindiaova.org>
2022-05-08 15:37:46 +03:00
David 'Epper' Marshall 650fb493bd
regex: add split (#14329) 2022-05-08 15:21:39 +03:00
Delyan Angelov 084f2867b6
time: let time.parse_rfc3339('2015-01-06T15:47:32.080254511Z') succeed (dockerd timestamps, Go's RFC3339Nano). 2022-05-08 14:54:57 +03:00
WoodyAtHome a0a3499bdc
net.smtp: correct date in smtp body (#14326) 2022-05-08 09:15:45 +03:00
Alexander Medvednikov 0526499d5f tools: hide tcc warning on macos for now 2022-05-08 08:01:55 +03:00
Merlin Diavova f8747d05dc
pg: add type 18 for pg boolean data type (#14335) 2022-05-08 07:17:43 +03:00
StunxFS d5e70552eb
checker: check error for `json.decode` (fix #6732) (#14305) 2022-05-08 07:17:11 +03:00
David 'Epper' Marshall aef95721a4
strings: builder: add clear (#14328) 2022-05-08 07:15:42 +03:00
yuyi b04d46770b
ast, checker, cgen: fix error for generic method with generic fn type argument (fix #14239) (#14333) 2022-05-07 20:22:20 +03:00
yuyi 724e7f037a
cgen: fix error for if cond with optional expr (#14334) 2022-05-07 20:20:00 +03:00
David 'Epper' Marshall a91226c376
docs: cleanup (#14327) 2022-05-07 20:18:42 +03:00
Delyan Angelov b53b1cc7cb
strings: reduce time spent in Builder.writeln (very frequently called) 2022-05-07 12:55:41 +03:00
Delyan Angelov 7ecd65221e
v.util: support -d trace_cached_read_source_file 2022-05-07 12:55:41 +03:00
Delyan Angelov 56cf0b0a2e
builtin: inline manually isnil calls in array.push_many (very frequently called) 2022-05-07 12:55:40 +03:00
Delyan Angelov 7f974a275a
docs: fix `teh` typo 2022-05-07 12:55:40 +03:00
Delyan Angelov f956acd2f6
ci: restore the `v -autofree .` step for gitly (gitly now has a workaround) 2022-05-07 12:55:40 +03:00
Delyan Angelov 9e8e364493
ci: comment out the go2v testing step for now 2022-05-07 12:55:39 +03:00
Alexander Medvednikov ca42ace367 Revert "checker: remove more unnecessary `void` errors"
This reverts commit 89c1e7f980.
2022-05-07 11:03:12 +03:00
Alexander Medvednikov 35cfa0da7c doc: closures work on arm64 too 2022-05-07 11:02:53 +03:00
playX 6a6c005dc0
checker: c2v fixes (#14332) 2022-05-07 09:50:41 +03:00
Alexander Medvednikov 9fb8de14dd
doc: closures now work on Windows 2022-05-07 09:49:33 +03:00
Alexander Medvednikov 89c1e7f980 checker: remove more unnecessary `void` errors 2022-05-07 09:09:18 +03:00
yuyi 70184ad1f8
scanner: minor simplification in scanner.v (#14331) 2022-05-07 08:30:15 +03:00
Alexander Medvednikov 14f06ead1b cgen: fix c2v consts; enum_decl() 2022-05-07 00:58:37 +03:00
yuyi 621574c12a
checker: fix error for generic method on nested struct (#14322) 2022-05-07 00:51:04 +03:00
Hunam 0699f324b5
builtin: add `map.values()` (#14301) 2022-05-06 20:42:01 +03:00
Lathanao ce99a306c0
net.http: make parse_form return POST requests with json data as a map with a `json` key, containing the json payload (#14289) 2022-05-06 20:23:36 +03:00
StunxFS 87de6df0e6
docs: update keyword list (#14319) 2022-05-06 20:17:45 +03:00
Ekopalypse 2027a1969b
v.builder: harmonise the default settings of the different Windows compilers (#14314) 2022-05-06 19:28:13 +03:00
Daniel Däschle 76cdf75299
builtin,cgen: rename `Option` to `_option` (#14317) 2022-05-06 19:25:54 +03:00
yuyi 45fe87c9e3
checker: minor cleanup in fn_call() (#14307) 2022-05-05 21:15:54 +03:00
yuyi 3091f31019
checker: check for optional argument in dump() (#14316) 2022-05-05 21:15:22 +03:00
Claudio Cesar de Sá 634796ae42
examples: 2 new examples for graph algorithms (topological sorting) (#14303) 2022-05-05 18:08:08 +03:00
Andréas Livet 9fde5b067b
docs: add missing function names in the `builtin` example doc comments (#14318) 2022-05-05 17:22:25 +03:00
Daniel Däschle 89fe82b732
checker: fix returning error on reference results (#14313) 2022-05-05 17:02:49 +03:00
yuyi b6058bfd6e
parser, checker: fix generic method on nested struct (fix #14089) (#14310) 2022-05-05 11:24:20 +03:00
playX 8afdb1c3ef
checker: c2v: allow passing fixed array as pointer to functions; bool <-> int (#14309) 2022-05-05 11:23:57 +03:00
StunxFS 7499506cf8
.gitignore: minor cleanup (#14279) 2022-05-05 10:17:24 +03:00
Delyan Angelov 785e9af8f1
ci: comment out the `v -autofree .` step for gitly temporarily 2022-05-05 09:20:08 +03:00
Delyan Angelov 7170a09382
vfmt: fix stackoverflow on long nested infix expressions 2022-05-05 07:41:43 +03:00
Delyan Angelov 01c1892995
tools: fix building `vdoctor.v` with `v build-tools` 2022-05-04 23:30:44 +03:00
Delyan Angelov a6b3e5d6a5
ci: wrap the too long line in README.md that failed `./v check-md -hide-warnings .` 2022-05-04 21:19:57 +03:00
Ned 76a7354506
builtin: add libbacktrace as option for generating stack traces (#14277) 2022-05-04 21:17:05 +03:00
yuyi 4242e7610f
checker: add comptime_selector() (#14286) 2022-05-04 19:25:58 +03:00
yuyi e2aa5c9b3f
parser: make peek_token_after_var_list() private (#14288) 2022-05-04 19:25:45 +03:00
Ikko Ashimine 223b96a59a
builtin: fix typo in array_bare.v (#14299) 2022-05-04 19:25:17 +03:00
Delyan Angelov 1a4d9017e2
builtin: improve support for large arrays (`[]int{len: 1_000_000_000}` now works), fix an arr.repeat() bug (#14294) 2022-05-04 18:42:06 +03:00
Alexander Medvednikov af8be14639
readme: minor github markdown fix 2022-05-04 18:06:41 +03:00
yuyi ac90a2b53d
checker: check error for fn call argument mismatch (fix #14280) (#14283) 2022-05-04 12:13:22 +03:00
playX 3bd6455178
checker: allow rune->any int and vice versa when translated (#14285) 2022-05-04 12:08:34 +03:00
Alexander Medvednikov 3d4b8dffdf checker: temporary c2v const fix 2022-05-04 08:28:27 +03:00
yuyi f321422964
checker, cgen: check comptime selector that has no field name (#14282) 2022-05-04 07:06:52 +03:00
Alexander Medvednikov 1e9156fd71 checker: c2v rune comparison fix 2022-05-04 06:49:45 +03:00
yuyi 3732db2bcc
cgen: cleanup in gen_array_contains_methods() (#14274) 2022-05-03 20:46:07 +03:00
playX 146051b231
checker: allow fixed array to pointer and vice versa when translated (#14275) 2022-05-03 20:44:45 +03:00
Delyan Angelov 04a77c731e
tests: add `// vtest flaky: true` to atomic_test.v 2022-05-03 20:42:12 +03:00
yuyi 63eacede95
checker: check argument mismatch of array.filter/all/any() (#14273) 2022-05-03 16:56:18 +03:00
Hunam 6da300428e
doc: add JS backend mention (#14265) 2022-05-03 12:51:12 +03:00
yuyi 276bd8060c
cgen: fix error for fixed array in operate (#14269) 2022-05-03 12:45:04 +03:00
Delyan Angelov 0e5c1cee48
builtin: improve musl/Alpine support (define weak backtrace/backtrace_symbols/backtrace_symbols_fd symbols) (#14250) 2022-05-03 09:17:53 +03:00
Delyan Angelov 4da2908d63
vdoc: fix panic on empty `//` comment on `v doc -f html file.v`; turn `expected code block after empty example` to a warning 2022-05-03 00:02:12 +03:00
StunxFS cf92224248
cleanup: delete x.v in project root folder (#14260) 2022-05-02 22:58:14 +03:00
Delyan Angelov ab1c265679
builtin: add missing panic_result_not_set/1 callback function. 2022-05-02 22:40:26 +03:00
spaceface db185598d2
checker: refactor comptime_if_branch (#14259) 2022-05-02 22:24:20 +03:00
yuyi 990afe37e1
checker: fix a bug in generics array init (#14258) 2022-05-02 16:18:33 +03:00
yuyi d72a25098a
parser: minor cleanup in interface_decl() (#14257) 2022-05-02 16:17:46 +03:00
yuyi 25c1b174ca
checker: fix generic fn infering fn type argument (fix #14243) (#14256) 2022-05-02 16:17:27 +03:00
yuyi b9cf2db6a8
parser: fix inline array's element access (#14253) 2022-05-02 16:16:32 +03:00
playX afbe6bf3a2
cgen: fix const decl gen when translated (#14255) 2022-05-02 15:01:59 +03:00
Isaiah a4fd349cf1
builder: allow `-compress` to work on windows too, when `upx` is installed (#14252)
Allow `-compress` flag on Windows if upx is installed. If upx not installed, same behavior as on linux/mac
2022-05-02 14:28:31 +03:00
yuyi 968d2b4654
cgen: fix fixed array init with `it` (#14251) 2022-05-02 02:00:45 +03:00
spaceface 332e821518
checker, gen: add support for a [minify] struct attribute (#14247) 2022-05-02 01:59:17 +03:00
Delyan Angelov aed2d0caf2
make files: add a `make check` target, that runs `v test-all` locally 2022-05-01 13:38:30 +03:00
David 'Epper' Marshall 91c1157810
time: relative update (#14240) 2022-05-01 10:47:05 +03:00
Daniel Däschle ec92d467d1
cgen: fix unsafe return error (#14233) 2022-04-30 17:31:28 +03:00
playX 0b54196962
checker: allow pointer index for translated code (#14231) 2022-04-30 17:30:55 +03:00
Daniel Däschle 9f8a34a528
all: rename result to _result (#14232) 2022-04-30 17:10:30 +03:00
Delyan Angelov 63d413f93c
tools: support `v missdoc .` instead of `v run cmd/tools/missdoc.v .` 2022-04-30 16:12:39 +03:00
Delyan Angelov c0b37409d2
tools: support a `v vet -p file.v` option that will warn about private functions with missing documentation 2022-04-30 16:09:30 +03:00
Delyan Angelov 8da42bfc85 tests: fix `./v -W build-tools` CI failure 2022-04-30 13:49:36 +03:00
Delyan Angelov 5277ce7dce
tests: support for marking _test.v files with `// vtest flaky: true`, to reduce false positives from the CI 2022-04-30 13:30:02 +03:00
David 'Epper' Marshall a2338dbb7c
docs: document more `builtin` functions/methods (#14229) 2022-04-30 12:31:23 +03:00
Delyan Angelov dcdfdf4dd8
tools: make `v up` more informative on failure 2022-04-30 10:11:02 +03:00
spaceface dab649ec8a
cgen: rewrite the closure implementation (#14223) 2022-04-30 09:32:46 +03:00
Alexander Medvednikov ce31a01a70 checker: allow voidptr arithmetic in translated code 2022-04-30 05:52:37 +03:00
yuyi cd30b6ea82
parser: make sure interface field names use uppercase letters (#14228) 2022-04-30 05:29:33 +03:00
Daniel Däschle 08fd0ce0de
all: basic implementation of result type (#14140) 2022-04-30 01:59:14 +03:00
StunxFS db185e6580
checker: check for reserved type names in `for in` (fix #14072) (#14212) 2022-04-30 01:25:29 +03:00
Benjamin Thomas 48eb40cd2c
doc: suggest a basic auto-reload setup (#14216) 2022-04-29 20:57:04 +03:00
David 'Epper' Marshall 881d0c04f1
time: add custom formatter (#14202) 2022-04-29 15:57:08 +03:00
yuyi ec865cfb37
parser: check interface methods name (fix #14217) (#14218) 2022-04-29 15:48:03 +03:00
yuyi 317acfda97
checker: check struct field name using uppercase letters (#14220) 2022-04-29 14:57:14 +03:00
Wertzui123 872f739396
builtin: ignore C++ 0xE06D7363 exception errors on windows (#14225) 2022-04-29 14:55:29 +03:00
StunxFS 995485c649
builtin: add `string.len_utf8()` method (#14208) 2022-04-29 10:23:57 +03:00
StunxFS 8b798acadd
cgen: fix use of C reserved words inside `defer` statement (fix #14101) (#14211) 2022-04-29 08:04:59 +03:00
Alexander Medvednikov 77645fcf35 builtin: define atoi & ftell 2022-04-29 04:31:51 +03:00
spaceface 14309594fe
ast: add a type_size() method (#14213) 2022-04-28 23:35:10 +03:00
David 'Epper' Marshall 5a42350a78
docs: add a `v fmt -w .` step in the contributing guide (#14210) 2022-04-28 23:31:22 +03:00
StunxFS e24482a143
transformer: minor optimization for `'string literal'.len` (#14207) 2022-04-28 22:35:16 +03:00
playX e56385d57d
checker: disable op overloading on structures for translated code (#14209) 2022-04-28 20:46:46 +03:00
yuyi 7aca67fb60
ast, parser: fix complex map init (#14206) 2022-04-28 17:37:19 +03:00
yuyi dd94ab890a
cgen: fix go anon fn call with ref argument (fix #14192) (#14197) 2022-04-28 14:43:20 +03:00
yuyi c802688690
ast: fix error for complex map operating (#14204) 2022-04-28 13:20:56 +03:00
Atom a225b25117
arrays: rephrase doc string (#14205) 2022-04-28 13:17:53 +03:00
Delyan Angelov 4538efd8f4
eval: small cleanup in the handling of `$if platform {` 2022-04-28 13:15:09 +03:00
Delyan Angelov e0ed8f8278
eval: make the interpreter backtrace more efficient and informative. 2022-04-28 12:31:30 +03:00
Delyan Angelov f72297c331
eval: add support for C.read/3, C.malloc/1, `$if openbsd {` 2022-04-28 11:30:36 +03:00
Delyan Angelov be04ec0620
pref: add support for `-thread-stack-size 4194304` (default set to 8MB) (#14168) 2022-04-28 08:46:33 +03:00
yuyi 7dd5d9ee61
checker: fix error for array of sumtype appending literal value (#14200) 2022-04-28 08:44:30 +03:00
yuyi 09f8b6a380
checker: check error in for_c_stmt with optional call (#14190) 2022-04-28 08:43:16 +03:00
tzSharing eb03fad934
gg: improve some loops in draw_rounded_rect* methods (#14195) 2022-04-27 22:57:48 +03:00
Delyan Angelov f53b9b4f12
ci: fix tcc compilation of atomic_test.v 2022-04-27 22:50:18 +03:00
Alexander Medvednikov 7dbfa86f25 all: atomic int fixes 2022-04-27 18:31:21 +03:00
yuyi 82ac39eca6
math: fix error for math.abs(0.0)/math.abs(0) (related #14165) (#14191) 2022-04-27 13:23:37 +03:00
yuyi 752e105f25
cgen: fix error for generic sumtype casting to typenode (#14188) 2022-04-27 11:32:43 +03:00
tzSharing 85f616877f
gg: fix gg.draw_rounded_rect_empty() graphical abnormalities and some optimizations (#14186) 2022-04-27 11:22:57 +03:00
playX b76095f28a
checker: allow + - * on pointers for translated code (#14183) 2022-04-26 21:00:44 +03:00
R cqls c26b7666c7
gg: some stuff required to have svg and png screenshots working on v ui (#14180) 2022-04-26 20:59:36 +03:00
yuyi be513b4c27
cgen: split up array_init() (#14178) 2022-04-26 20:58:47 +03:00
Larpon 1c48a8d760
strconv: add missing doc strings (#14164) 2022-04-26 18:09:36 +03:00
yuyi 660201c188
cgen: fix error for cast to empty interface (fix #14162) (#14176) 2022-04-26 13:26:48 +03:00
Brian Callahan b9a0e2d285
sokol: support compilation on OpenBSD (#14169) 2022-04-26 13:14:00 +03:00
yuyi 38afd74d26
ast, checker, cgen: fix error for multi-return in or expr (fix #14167) (#14172) 2022-04-26 12:17:05 +03:00
playX 95880dfe5c
checker: allow indexing through alias to int (#14177) 2022-04-26 12:15:35 +03:00
playX dce2173ac9
checker: c2v fixes (#14161) 2022-04-26 01:34:26 +03:00
Alexander Medvednikov 501b293e84 checker: remove already handled "undefined" errors 2022-04-25 16:53:34 +03:00
Larpon d799abd139
regex: rephrase doc string (#14159) 2022-04-25 16:03:13 +03:00
yuyi e42dc8e228
checker: fix error for match aliases (#14157) 2022-04-25 14:42:43 +03:00
yuyi f89c81087b
checker: check error for array.index() argument (#14147) 2022-04-25 14:42:31 +03:00
yuyi aeba110d01
cgen: fix error for printing multi fixed array (#14141) 2022-04-25 14:42:05 +03:00
Larpon 283d181047
cli: add missing doc strings (#14158) 2022-04-25 14:41:46 +03:00
yuyi 88f22b4367
cgen: fix error for anon fn decl inside ternary (#14150) 2022-04-25 12:36:03 +03:00
Delyan Angelov 60e205a193
tests: add ability to check the output of commands for .starts_with, .ends_with and .contains strings, in `v test-all` 2022-04-25 12:20:38 +03:00
Delyan Angelov d35d67c2bd
eval: enable `v interpret examples/hanoi.v` 2022-04-25 12:20:37 +03:00
Nick Treleaven d8a5df9044
checker: error if smaller signed == unsigned (#14078) 2022-04-25 12:09:25 +03:00
Delyan Angelov 147e6e669f
cgen: fix pushing to an array of string pointers (fix #14156) 2022-04-25 11:26:24 +03:00
yuyi 922cee9162
parser, checker, cgen: fix error for fn call using anon fn call argument (#14155) 2022-04-25 11:26:14 +03:00
Delyan Angelov 1291b621f6
ci: bump test retries for go_anon_fn_variable_call_test.v to 3 2022-04-25 10:32:41 +03:00
fleur ddbe812f1b
cgen: add callconv support for fns from ptr (#14151) 2022-04-25 08:51:03 +03:00
Haren S 11ee2b6409
builder: improve macOS 10.5 and PPC support (#14152) 2022-04-25 08:17:00 +03:00
stackotter 563469ed9f
vfmt: fix array_init line wrapping (#14154) 2022-04-25 08:11:44 +03:00
yuyi c819f0f86f
checker, cgen: fix printing in 'for v in a' (#14146) 2022-04-24 13:30:13 +03:00
Alexander Medvednikov 9355048b6c tmpl: minor fixes and optimizations 2022-04-23 16:01:44 +03:00
Delyan Angelov 3388caa6c5
ci: bump vtest retry to 6 for channel_select_test.v (fails sporadically in the windows-gcc job) 2022-04-23 15:36:19 +03:00
Delyan Angelov 365e7d6b34
vfmt: ignore parser warnings, cleanup code 2022-04-23 11:10:12 +03:00
yuyi d934472b17
checker: simplify checking array.contains() argument (#14133) 2022-04-22 22:34:13 +03:00
yuyi b86320a669
parser: minor cleanup in stmt() (#14136) 2022-04-22 22:33:13 +03:00
Claudio Cesar de Sá a2db44bc38
examples: add 2 more graph search examples (DFS and BFS), move them into `examples/graphs` (#14131) 2022-04-22 12:01:29 +03:00
yuyi 5dce091379
checker, cgen: fix generic empty interface to multi struct (#14132) 2022-04-22 11:02:51 +03:00
Alexander Medvednikov 9b565bf765 cgen: fix enum switch bug in translated code 2022-04-22 02:31:32 +03:00
tzSharing 03d21a727e
gg: fix gg.draw_rounded_rect_filled() graphical abnormalities (#14128) 2022-04-22 00:16:10 +03:00
Larpon 506259adb6
os: add behavior info to `is_dir_empty` documentation (#14110) 2022-04-21 18:21:00 +03:00
yuyi 26b0e7fd34
fmt: remove extra parentheses (#14125) 2022-04-21 18:20:32 +03:00
Delyan Angelov 2080557f50
ast: allow `a := match x { 101 { ... for {...} ... y }` 2022-04-21 13:31:06 +03:00
yuyi 8a18f9175a
cgen: fix error for if expr with nested match expr (#14122) 2022-04-21 13:02:31 +03:00
yuyi 448938be0d
parser: fix generic anon fn decl with type only argument (#14124) 2022-04-21 12:53:13 +03:00
yuyi 99eb9fdaab
checker: fix error for fn with array of aliases argument (#14123) 2022-04-21 12:52:09 +03:00
yuyi f13583b04a
checker: check array builtin method's arguments (#14119) 2022-04-21 12:51:04 +03:00
yuyi 8013bd43b0
checker: check map builtin method's arguments (#14120) 2022-04-21 12:49:46 +03:00
Delyan Angelov 5e8c4a3aff
ci: enable again the `v install ui` task 2022-04-21 11:21:59 +03:00
StunxFS 2a0b372d0d
tools: minor cleanup in fast.v (#14117) 2022-04-21 10:46:35 +03:00
ChAoS_UnItY c5824c36f2
checker, cgen: allow static (fixed) arrays in `in` operator (#14121) 2022-04-21 10:32:29 +03:00
Delyan Angelov c789ea5a15
ci: temporarily use `git clone https://github.com/vlang/xyz ~/.vmodules/xyz` instead of `v install xyz` 2022-04-21 09:20:15 +03:00
sunnylcw 4491b535ec
doc: add link to V's standard library documentation at the start (#14114) 2022-04-21 00:26:20 +03:00
Delyan Angelov 31b28af179
bootstrap: remove -I ./thirdparty/stdatomic/nix from make files (#14111) 2022-04-21 00:12:50 +03:00
lemon 960225f7a7
builtin: fix `-cc gcc -gc boehm` on linux and macos (#14115) 2022-04-21 00:12:17 +03:00
Nick Treleaven 1533b77404
builtin: remove unnecessary casts for defunct small unsigned warning (#14108) 2022-04-20 21:47:09 +03:00
yuyi 0260c2a552
checker: minor cleanup in assign_stmt() (#14107) 2022-04-20 21:03:41 +03:00
Hunam 0374f021c5
os: small cleanup of function description (#14112) 2022-04-20 20:58:41 +03:00
mjh 1546645f63
datatypes: fix bst child access, when .root is 0 (#14080) 2022-04-20 16:49:18 +03:00
Larpon a1342e85c3
os: add info about overwritten content to `write_file` (#14109) 2022-04-20 15:29:58 +03:00
yuyi 52ea0b8cc3
ast: minor cleanup of types.v (#14103) 2022-04-20 14:24:13 +03:00
yuyi ce4c2afc9c
checker, cgen: use 'stmts.last()' instead of 'stmts[stmts.len - 1]' (#14105) 2022-04-20 14:23:32 +03:00
yuyi 44ba19716b
checker: fix error for fn with multi return (#14095) 2022-04-20 13:09:40 +03:00
yuyi 0c3b69eaef
checker: fix error for assign array of aliases (#14096) 2022-04-20 13:08:47 +03:00
Alexander Medvednikov 364656b312 builtin: define C.abs() 2022-04-20 13:03:30 +03:00
Isaiah 0887b59254
vpm: fix get_all_modules() (#14097) 2022-04-20 12:15:30 +03:00
yuyi 8cc79e4299
checker: check error for arguments of array.contains() (#14102) 2022-04-20 11:00:59 +03:00
playX 711e90cf99
v.util: add math to builtin_module_names (temporary fix for C2V) (#14100) 2022-04-20 10:57:55 +03:00
playX f6a0c26a85
checker: c2v fixes (#14091) 2022-04-20 01:09:34 +03:00
Delyan Angelov 9646e4b9d8
sync: use #insert for atomic.h, so that bootstrapping can be simplified 2022-04-19 20:06:20 +03:00
Delyan Angelov 006df58451
checker, cgen: add support for #insert, to simplify bootstrapping V 2022-04-19 19:37:04 +03:00
JalonSolov daf5d32327
checker: fix error message when number of generic parameters is incorrect (#14090) 2022-04-19 18:34:23 +03:00
yuyi a318a2e09e
examples: fix optional in string interpolation and format error (#14079) 2022-04-19 13:29:53 +03:00
yuyi e16ce3af88
token: minor cleanup of token.v (#14083) 2022-04-19 13:28:27 +03:00
yuyi 6164654d11
checker: check fn return type mismatch (#14081) 2022-04-19 13:04:41 +03:00
Nick Treleaven 4400efeb9f
checker: Revert part of small_unsigned == signed (#13967) (#14075)
`gcc -W` doesn't error for e.g. u16 == i32, only for u32 == i16.
Any u16 value can fit in an i32.
2022-04-18 21:30:09 +03:00
yuyi 7ef64bde50
checker: check error for fn decl with optional arguments (#14076) 2022-04-18 21:22:31 +03:00
yuyi d0a11f50ca
cgen: minor cleanup of infix_expr.v (#14070) 2022-04-18 15:05:19 +03:00
Delyan Angelov 379b638b57
ci: update windows-install-sqlite.bat to latest sqlite 2022-04-18 14:25:57 +03:00
yuyi fe371845da
ast, checker, cgen: fix aggregations type check (#14066) 2022-04-18 12:38:08 +03:00
spaceface 775c4c34b5
builtin: compile the gc statically by default (#14063) 2022-04-18 10:50:21 +03:00
Ikko Ashimine 56a3539ea9
io: fix typo in readerwriter.v (#14060)
seperate -> separate
2022-04-17 17:40:14 +03:00
yuyi 17c34b09a6
checker, cgen: minor cleanup of last expr stmt expression (#14057) 2022-04-17 14:08:43 +03:00
yuyi cb44f5981e
checker, cgen: fix error for if expr with generic sumtype (#14056) 2022-04-17 08:19:44 +03:00
Vincenzo Palazzo 4f14f7714f
checker: ensure that the variant SubType exists (#14053)
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2022-04-16 19:29:10 +03:00
Vincenzo Palazzo 48486e1afb
ci: reformatted tools/vcreate.v (#14054)
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2022-04-16 19:09:08 +03:00
Cameron Katri 1fc54a1e5b
vcreate: Allow custom default license (#14046) 2022-04-16 17:43:25 +03:00
Delyan Angelov 8a57f7ed2d
v.util: always compile vfmt with `-d vfmt` to enable more efficient parsing 2022-04-16 14:05:55 +03:00
Julien de Carufel 16ead4e63c
cgen: fix infix generics bug (#14048) 2022-04-16 13:23:19 +03:00
Alexander Medvednikov 43931a8e77
doc: byte => u8 2022-04-16 13:02:56 +03:00
Delyan Angelov 5b7e538119
v.pref: show the VCROSS_COMPILER_NAME notice only when the output is not a .c file 2022-04-16 10:46:03 +03:00
Delyan Angelov 4a71b27c52
ci: add test_byte_vs_u8 to int_test.v 2022-04-15 21:42:07 +03:00
Delyan Angelov d75c408868
ci: fix typeof_simple_types_test.v 2022-04-15 21:22:32 +03:00
Delyan Angelov 82c5621621
ci: fix typeof_simple_types_test.v 2022-04-15 21:21:44 +03:00
Delyan Angelov 675f8b6300
ci: fix generic_fn_infer_struct_test.v 2022-04-15 21:21:12 +03:00
Delyan Angelov ad231cec2f
ci: fix code_test.v 2022-04-15 21:20:03 +03:00
Delyan Angelov 87a373d82c
ci: fix coutput_test.v 2022-04-15 21:18:55 +03:00
Delyan Angelov c7aedb8e8d
ci: fix fmt_test.v 2022-04-15 21:16:31 +03:00
Delyan Angelov 375361b787
ci: fix `./v check-md -hide-warnings .` 2022-04-15 21:08:09 +03:00
Delyan Angelov 840f474fb5
ci: fix `./v -progress test-cleancode` 2022-04-15 21:04:10 +03:00
Delyan Angelov e802e0b9cb
ci: fix more test-all failures 2022-04-15 21:02:03 +03:00
Delyan Angelov bb2a324d61
ci: more gen.js fixes 2022-04-15 20:51:04 +03:00
Delyan Angelov 868d3e1008
ci: fix failing tests for mysql, crypto.rc4, strings 2022-04-15 20:51:04 +03:00
Alexander Medvednikov c03fe020bf parser: do not allow [x]byte{} 2022-04-15 20:40:37 +03:00
Delyan Angelov 6f5a513d8b
ci: fix `v build-examples` 2022-04-15 20:31:10 +03:00
Delyan Angelov e18cb9748f
ci: fix `v check-md doc/docs.md` 2022-04-15 20:25:19 +03:00
Delyan Angelov 173e6a943b
checker: fix tests (adjust byte to u8 in .out files too) 2022-04-15 20:15:03 +03:00
Delyan Angelov cc8803c602
builtin: fix failing embed_file_test.v (`pub fn (data &u8) vbytes(len int) []u8 {`) 2022-04-15 19:57:00 +03:00
Alexander Medvednikov 78cb6e2b41 all: handle fixed []u8 2022-04-15 18:35:56 +03:00
Alexander Medvednikov 1c6f63ac0a tests: use u8 everywhere 2022-04-15 18:34:15 +03:00
Alexander Medvednikov fbb9e65c0f all: ~500 more byte=>u8 2022-04-15 18:25:45 +03:00
Alexander Medvednikov ae6a25f44e websocket, utf: u8 fixes 2022-04-15 16:24:02 +03:00
Alexander Medvednikov e97ebf8cfc sokol: byte => u8 2022-04-15 16:12:05 +03:00
Alexander Medvednikov 258d1f77dc net: fix byte buffers 2022-04-15 15:57:45 +03:00
Alexander Medvednikov af73e195da net: byte fixes 2022-04-15 15:55:39 +03:00
Alexander Medvednikov fb192d949b all: replace []byte with []u8 2022-04-15 15:35:35 +03:00
Alexander Medvednikov 0527ac633e ast: remove .byte 2022-04-15 15:30:37 +03:00
Alexander Medvednikov dbcf6e9c33 os: fix Process on windows 2022-04-15 15:23:05 +03:00
Alexander Medvednikov c14984899b builtin: fix windows fn definitions 2022-04-15 15:18:21 +03:00
Alexander Medvednikov a1372e284c builtin: update alloc fn definitions 2022-04-15 15:16:10 +03:00
Alexander Medvednikov c3ad4e2069 encoding.base64: use u8 2022-04-15 15:10:34 +03:00
Alexander Medvednikov d4a0d6f73c all: byte => u8 2022-04-15 14:58:56 +03:00
Alexander Medvednikov b49d873217 builtin: [1000]u8 fix 2022-04-15 14:48:39 +03:00
Alexander Medvednikov 014c3c97f0 all: byte => u8 2022-04-15 14:45:52 +03:00
Alexander Medvednikov 7f3b91e688 builtin: more byte => u8 2022-04-15 14:10:11 +03:00
Alexander Medvednikov 1e7eb713fb cgen: remove byte references from cheaders.v 2022-04-15 14:04:53 +03:00
Alexander Medvednikov ba7b329c73 builtin: more byte=>u8 2022-04-15 13:55:56 +03:00
Alexander Medvednikov e6ff1508d2 all: make u8 the primary type, byte the alias 2022-04-15 13:43:03 +03:00
1064 changed files with 59626 additions and 34297 deletions

View File

@ -15,6 +15,8 @@ ls -lat
## try running the known failing tests first to get faster feedback
./v test vlib/builtin/string_test.v vlib/strings/builder_test.v
./v test-cleancode
./v test-self
./v build-vbinaries

View File

@ -33,6 +33,7 @@ jobs:
run: |
echo $VFLAGS
make
./v test-cleancode
./v -d debug_malloc -d debug_realloc -o v cmd/v
./v -cg -cstrict -o v cmd/v
# Test v -realloc arena allocation
@ -54,6 +55,8 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: ./v test-self
# - name: Self tests (-cstrict)
@ -125,13 +128,15 @@ jobs:
run: |
./v -gc boehm cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests with `-gc boehm` with V compiler using Boehm-GC itself
run: ./v -gc boehm test-self
- name: Test leak detector
run: |
./v -gc boehm_leak -o testcase_leak vlib/v/tests/testcase_leak.vv
./testcase_leak 2>leaks.txt
grep "Found 1 leaked object" leaks.txt && grep ", sz=1000," leaks.txt
grep "Found 1 leaked object" leaks.txt && grep -P ", sz=\s?1000," leaks.txt
- name: Test leak detector not being active for `-gc boehm`
run: |
./v -gc boehm -o testcase_leak vlib/v/tests/testcase_leak.vv
@ -188,6 +193,8 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: VJOBS=1 ./v test-self
- name: Build examples
@ -280,6 +287,8 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: ./v test-self
- name: Self tests (-prod)
@ -372,6 +381,8 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: ./v test-self
- name: Self tests (-prod)
@ -429,7 +440,7 @@ jobs:
- name: Test new v.c
run: |
.\v.exe -o v.c cmd/v
gcc -Werror -I ./thirdparty/stdatomic/win -municode -w v.c
gcc -Werror -municode -w v.c
- name: Install dependencies
run: |
.\v.exe setup-freetype
@ -442,6 +453,8 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: .\v.exe test-self
# - name: Test
@ -500,6 +513,9 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
### TODO: test-cleancode fails with msvc. Investigate why???
## - name: All code is formatted
## run: ./v test-cleancode
- name: Self tests
run: |
./v -cg cmd\tools\vtest-self.v
@ -534,7 +550,7 @@ jobs:
- name: Test new v.c
run: |
.\v.exe -o v.c cmd/v
.\thirdparty\tcc\tcc.exe -I ./thirdparty/stdatomic/win -Werror -w -ladvapi32 -bt10 v.c
.\thirdparty\tcc\tcc.exe -Werror -w -ladvapi32 -bt10 v.c
- name: Install dependencies
run: |
.\v.exe setup-freetype
@ -555,8 +571,8 @@ jobs:
run: ./v doc -v clipboard
- name: Test v build-tools
run: ./v -W build-tools
- name: Test ./v doc clipboard
run: ./v doc clipboard
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: ./v test-self
- name: Test v->js
@ -575,7 +591,7 @@ jobs:
## .\v.exe wipe-cache
## .\make.bat -tcc32
## - name: Test new v.c
## run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -I ./thirdparty/stdatomic/win -Werror -g -w -ladvapi32 -bt10 v.c
## run: .\v.exe -o v.c cmd/v && .\thirdparty\tcc\tcc.exe -Werror -g -w -ladvapi32 -bt10 v.c
## - name: v doctor
## run: ./v doctor
##

View File

@ -14,7 +14,7 @@ jobs:
timeout-minutes: 30
env:
VFLAGS: -cc tcc -no-retry-compilation
B_CFLAGS: -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w
B_CFLAGS: -g -std=gnu11 -w
B_LFLAGS: -lm -lpthread
steps:
- uses: actions/checkout@v2
@ -52,7 +52,7 @@ jobs:
timeout-minutes: 30
env:
VFLAGS: -cc clang
B_CFLAGS: -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w
B_CFLAGS: -g -std=gnu11 -w
B_LFLAGS: -lm -lpthread
steps:
- uses: actions/checkout@v2

View File

@ -71,14 +71,14 @@ jobs:
- name: v.c can be compiled and run with -os cross
run: |
./v -os cross -o /tmp/v.c cmd/v
gcc -g -std=gnu11 -I ./thirdparty/stdatomic/nix -w -o v_from_vc /tmp/v.c -lm -lpthread
gcc -g -std=gnu11 -w -o v_from_vc /tmp/v.c -lm -lpthread
ls -lart v_from_vc
./v_from_vc version
- name: v_win.c can be compiled and run with -os windows
run: |
./v -cc msvc -os windows -o /tmp/v_win.c cmd/v
x86_64-w64-mingw32-gcc -I ./thirdparty/stdatomic/win /tmp/v_win.c -std=c99 -w -municode -o v_from_vc.exe
x86_64-w64-mingw32-gcc /tmp/v_win.c -std=c99 -w -municode -o v_from_vc.exe
ls -lart v_from_vc.exe
wine64 ./v_from_vc.exe version

View File

@ -91,7 +91,9 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v
run: make && ./v -cg -cstrict -o v cmd/v
- name: Ensure code is well formatted
run: ./v test-cleancode
- name: Self tests (-fsanitize=undefined)
run: ./v -cflags "-fsanitize=undefined" -o v2 cmd/v && ./v2 -cflags -fsanitize=undefined test-self
- name: Build examples (V compiled with -fsanitize=undefined)
@ -115,7 +117,9 @@ jobs:
sudo apt-get install --quiet -y postgresql libpq-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
- name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v
run: make && ./v -cg -cstrict -o v cmd/v
- name: Ensure code is well formatted
run: ./v test-cleancode
- name: Self tests (-fsanitize=undefined)
run: ./v -cflags "-fsanitize=undefined" -o v2 cmd/v && ./v2 -cflags -fsanitize=undefined test-self
- name: Build examples (V compiled with -fsanitize=undefined)
@ -140,7 +144,9 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v
run: make && ./v -cg -cstrict -o v cmd/v
- name: Ensure code is well formatted
run: ./v test-cleancode
- name: Self tests (-fsanitize=address)
run: ASAN_OPTIONS=detect_leaks=0 ./v -cflags "-fsanitize=address,pointer-compare,pointer-subtract" test-self
- name: Self tests (V compiled with -fsanitize=address)
@ -168,6 +174,11 @@ jobs:
echo $VFLAGS
.\make.bat -msvc
.\v.exe self
- name: Ensure code is well formatted
run: |
.\v.exe fmt -verify vlib/builtin/ vlib/v/scanner/ vlib/v/parser/ vlib/v/gen/
## TODO: check to see why `v test-cleancode` does not work with msvc on windows
## - name: Install dependencies
## run: |
## .\v.exe setup-freetype
@ -195,7 +206,9 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cg -cstrict -o v cmd/v
run: make && ./v -cg -cstrict -o v cmd/v
- name: Ensure code is well formatted
run: ./v test-cleancode
- name: Self tests (-fsanitize=address)
run: ASAN_OPTIONS=detect_leaks=0 ./v -cflags -fsanitize=address test-self
- name: Self tests (V compiled with -fsanitize=address)
@ -224,11 +237,14 @@ jobs:
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install clang
- name: Build V
run: make -j4 && ./v -cc clang -cg -cstrict -o v cmd/v
run: make && ./v -cc clang -cg -cstrict -o v cmd/v
- name: Ensure code is well formatted
run: ./v test-cleancode
- name: Self tests (-fsanitize=memory)
run: ./v -cflags -fsanitize=memory test-self
- name: Self tests (V compiled with -fsanitize=memory)
run:
./v -cflags -fsanitize=memory -o v cmd/v && ./v -cc tcc test-self -msan-compiler
run: |
./v -cflags -fsanitize=memory -o v cmd/v
./v -cc tcc test-self -msan-compiler
- name: Build examples (V compiled with -fsanitize=memory)
run: ./v build-examples

View File

@ -42,6 +42,9 @@ jobs:
- name: Build V
run: CC=gcc make
- name: All code is formatted
run: ./v test-cleancode
- name: Test V fixed tests
run: ./v test-self
@ -69,5 +72,9 @@ jobs:
echo $VFLAGS
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Test V fixed tests
run: ./v test-self

View File

@ -25,12 +25,13 @@ jobs:
.\v.exe setup-freetype
.\.github\workflows\windows-install-sqlite.bat
- name: v doctor
run: |
./v doctor
run: ./v doctor
- name: Verify `v test` works
run: |
./v cmd/tools/test_if_v_test_system_works.v
./cmd/tools/test_if_v_test_system_works
- name: All code is formatted
run: ./v test-cleancode
- name: Self tests
run: |
./v -cg cmd\tools\vtest-self.v

View File

@ -85,6 +85,7 @@ jobs:
- name: g++ version
run: g++-9 --version
- name: V self compilation with g++
continue-on-error: true
run: ./v -cc g++-9 -no-std -cflags -std=c++11 -o v2 cmd/v && ./v2 -cc g++-9 -no-std -cflags -std=c++11 -o v3 cmd/v
## - name: Running tests with g++
## run: ./v -cc g++-9 test-self
@ -93,6 +94,7 @@ jobs:
run: ./v -autofree -o v2 cmd/v ## NB: this does not mean it runs, but at least keeps it from regressing
- name: Shader examples can be build
continue-on-error: true
run: |
wget https://github.com/floooh/sokol-tools-bin/raw/33d2e4cc26088c6c28eaef5467990f8940d15aab/bin/linux/sokol-shdc
chmod +x ./sokol-shdc
@ -146,116 +148,3 @@ jobs:
./v test-parser -S examples/regex_example_fuzz.v
./v test-parser -S examples/2048/2048_fuzz.v
v-apps-compile:
runs-on: ubuntu-20.04
timeout-minutes: 121
steps:
- uses: actions/checkout@v2
- name: Build V
run: make && sudo ./v symlink
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --quiet -y libgc-dev
sudo apt-get install --quiet -y libsodium-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install --quiet -y xfonts-75dpi xfonts-base
## vls
- name: Clone VLS
run: git clone --depth 1 https://github.com/vlang/vls
- name: Build VLS
run: pushd vls; v cmd/vls ; popd
- name: Build VLS with -prod
run: pushd vls; v -prod cmd/vls; popd
- name: Build VLS with -gc boehm -skip-unused
run: pushd vls; v -gc boehm -skip-unused cmd/vls; popd
## vsl
- name: Clone VSL
run: git clone --depth 1 https://github.com/vlang/vsl ~/.vmodules/vsl
- name: Install dependencies
run: sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
- name: Execute Tests using Pure V Backend
run: ~/.vmodules/vsl/bin/test
- name: Execute Tests using Pure V Backend with Pure V Math
run: ~/.vmodules/vsl/bin/test --use-cblas
- name: Execute Tests using Pure V Backend and Garbage Collection enabled
run: ~/.vmodules/vsl/bin/test --use-gc boehm
- name: Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled
run: ~/.vmodules/vsl/bin/test --use-cblas --use-gc boehm
## vtl
- name: Clone VTL
run: git clone --depth 1 https://github.com/vlang/vtl ~/.vmodules/vtl
- name: Install dependencies
run: sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
- name: Execute Tests using Pure V Backend
run: ~/.vmodules/vtl/bin/test
- name: Execute Tests using Pure V Backend with Pure V Math
run: ~/.vmodules/vtl/bin/test --use-cblas
- name: Execute Tests using Pure V Backend and Garbage Collection enabled
run: ~/.vmodules/vtl/bin/test --use-gc boehm
- name: Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled
run: ~/.vmodules/vtl/bin/test --use-cblas --use-gc boehm
## vab
- name: Clone vab
run: git clone --depth 1 https://github.com/vlang/vab
- name: Build vab
run: cd vab; ../v ./vab.v ; cd ..
- name: Build vab with -gc boehm -skip-unused
run: cd vab; ../v -gc boehm -skip-unused ./vab.v ; cd ..
## gitly
- name: Install markdown
run: ./v install markdown
- name: Build Gitly
run: |
git clone --depth 1 https://github.com/vlang/gitly
cd gitly
../v .
# ./gitly -ci_run
../v -autofree .
../v -o x tests/first_run.v
./x
cd ..
## vex
- name: Install Vex dependencies
run: sudo apt-get install --quiet -y libsodium-dev libssl-dev sqlite3 libsqlite3-dev
- name: Install Vex
run: mkdir -p ~/.vmodules/nedpals; git clone https://github.com/nedpals/vex ~/.vmodules/nedpals/vex
- name: Compile all of the Vex examples
run: ./v should-compile-all ~/.vmodules/nedpals/vex/examples
- name: Compile the simple Vex example with -gc boehm -skip-unused
run: ./v -gc boehm -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
- name: Run Vex Tests
run: ./v test ~/.vmodules/nedpals/vex
## vpm modules
- name: Install UI through VPM
run: ./v install ui
## libsodium
- name: Install libsodium-dev package
run: sudo apt-get install --quiet -y libsodium-dev
- name: Installl the libsodium wrapper through VPM
run: ./v install libsodium
- name: Test libsodium
run: VJOBS=1 ./v -stats test ~/.vmodules/libsodium
## Go2V
- name: Clone & Build go2v
run: git clone --depth=1 https://github.com/vlang/go2v go2v/
- name: Build go2v
run: ./v go2v/
- name: Run tests for go2v
run: VJOBS=1 ./v -stats test go2v/
## vlang/pdf
- name: Clone & Build vlang/pdf
run: git clone --depth=1 https://github.com/vlang/pdf ~/.vmodules/pdf/
- name: PDF examples should compile
run: ./v should-compile-all ~/.vmodules/pdf/examples

View File

@ -0,0 +1,145 @@
name: V Apps and Modules
on:
push:
paths-ignore:
- "**.md"
pull_request:
paths-ignore:
- "**.md"
concurrency:
group: build-other-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true
jobs:
v-apps-compile:
runs-on: ubuntu-20.04
timeout-minutes: 121
steps:
- uses: actions/checkout@v2
- name: Build V
run: make && sudo ./v symlink
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --quiet -y libgc-dev
sudo apt-get install --quiet -y libsodium-dev libssl-dev sqlite3 libsqlite3-dev valgrind
sudo apt-get install --quiet -y libfreetype6-dev libxi-dev libxcursor-dev libgl-dev
sudo apt-get install --quiet -y xfonts-75dpi xfonts-base
- name: Install UI through VPM
continue-on-error: true
run: |
echo "Official VPM modules should be installable"
./v install ui
- name: Build V Language Server (VLS)
continue-on-error: true
run: |
echo "Clone VLS"
git clone --depth 1 https://github.com/vlang/vls
echo "Build VLS"
pushd vls; v cmd/vls ; popd
echo "Build VLS with -prod"
pushd vls; v -prod cmd/vls; popd
echo "Build VLS with -gc boehm -skip-unused"
pushd vls; v -gc boehm -skip-unused cmd/vls; popd
- name: Build VSL
continue-on-error: true
run: |
git clone --depth 1 https://github.com/vlang/vsl ~/.vmodules/vsl
sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
echo "Execute Tests using Pure V Backend"
~/.vmodules/vsl/bin/test
echo "Execute Tests using Pure V Backend with Pure V Math"
~/.vmodules/vsl/bin/test --use-cblas
echo "Execute Tests using Pure V Backend and Garbage Collection enabled"
~/.vmodules/vsl/bin/test --use-gc boehm
echo "Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled"
~/.vmodules/vsl/bin/test --use-cblas --use-gc boehm
- name: Build VTL
continue-on-error: true
run: |
echo "Clone VTL"
git clone --depth 1 https://github.com/vlang/vtl ~/.vmodules/vtl
echo "Install dependencies"
sudo apt-get install --quiet -y --no-install-recommends gfortran liblapacke-dev libopenblas-dev libgc-dev
echo "Execute Tests using Pure V Backend"
~/.vmodules/vtl/bin/test
echo "Execute Tests using Pure V Backend with Pure V Math"
~/.vmodules/vtl/bin/test --use-cblas
echo "Execute Tests using Pure V Backend and Garbage Collection enabled"
~/.vmodules/vtl/bin/test --use-gc boehm
echo "Execute Tests using Pure V Backend with Pure V Math and Garbage Collection enabled"
~/.vmodules/vtl/bin/test --use-cblas --use-gc boehm
- name: Build VAB
continue-on-error: true
run: |
echo "Clone vab"
git clone --depth 1 https://github.com/vlang/vab
echo "Build vab"
cd vab; ../v ./vab.v ; cd ..
echo "Build vab with -gc boehm -skip-unused"
cd vab; ../v -gc boehm -skip-unused ./vab.v ; cd ..
- name: Build Gitly
continue-on-error: true
run: |
echo "Clone markdown"
git clone https://github.com/vlang/markdown ~/.vmodules/markdown
echo "Clone Gitly"
git clone --depth 1 https://github.com/vlang/gitly
cd gitly
echo "Build Gitly"
../v .
echo "Build Gitly with -autofree"
../v -autofree .
echo "Run first_run.v"
../v run tests/first_run.v
# ./gitly -ci_run
- name: Build libsodium
continue-on-error: true
run: |
echo "Install libsodium-dev package"
sudo apt-get install --quiet -y libsodium-dev
echo "Clone the libsodium wrapper"
git clone https://github.com/vlang/libsodium ~/.vmodules/libsodium
echo "Test libsodium"
VJOBS=1 ./v -stats test ~/.vmodules/libsodium
- name: Build VEX
continue-on-error: true
run: |
echo "Install Vex dependencies"
sudo apt-get install --quiet -y libsodium-dev libssl-dev sqlite3 libsqlite3-dev
echo "Clone Vex"
mkdir -p ~/.vmodules/nedpals; git clone https://github.com/nedpals/vex ~/.vmodules/nedpals/vex
echo "Compile all of the Vex examples"
./v should-compile-all ~/.vmodules/nedpals/vex/examples
echo "Compile the simple Vex example with -gc boehm -skip-unused"
./v -gc boehm -skip-unused ~/.vmodules/nedpals/vex/examples/simple_example.v
echo "Run Vex Tests"
./v test ~/.vmodules/nedpals/vex
- name: Build go2v
continue-on-error: true
run: |
echo "Clone go2v"
clone --depth=1 https://github.com/vlang/go2v go2v/
echo "Build go2v"
./v go2v/
## echo "Run tests for go2v"
## VJOBS=1 ./v -stats test go2v/
- name: Build vlang/pdf
continue-on-error: true
run: |
git clone --depth=1 https://github.com/vlang/pdf ~/.vmodules/pdf/
echo "PDF examples should compile"
./v should-compile-all ~/.vmodules/pdf/examples

View File

@ -1,12 +1,11 @@
@echo off
curl -L https://www.sqlite.org/2020/sqlite-amalgamation-3320300.zip -o sqlite-amalgamation-3320300.zip
curl -L https://www.sqlite.org/2022/sqlite-amalgamation-3380200.zip -o sqlite-amalgamation-3380200.zip
unzip sqlite-amalgamation-3320300.zip -d thirdparty\
unzip sqlite-amalgamation-3380200.zip -d thirdparty\
del thirdparty\sqlite-amalgamation-3320300\shell.c
del thirdparty\sqlite-amalgamation-3380200\shell.c
move /y thirdparty\sqlite-amalgamation-3320300 thirdparty\sqlite
move /y thirdparty\sqlite-amalgamation-3380200 thirdparty\sqlite
dir thirdparty\sqlite

View File

@ -0,0 +1,32 @@
matrix:
PLATFORM:
- 'linux/amd64'
- 'linux/arm64'
platform: ${PLATFORM}
branches: ['master']
depends_on:
- 'vc'
pipeline:
build:
image: 'menci/archlinuxarm:base-devel'
commands:
# Update packages
- pacman -Syu --noconfirm
# Create non-root user to perform build & switch to their home
- groupadd -g 1000 builder
- useradd -mg builder builder
- chown -R builder:builder "$PWD"
- "echo 'builder ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers"
- su builder
# Build the package
- makepkg -s --noconfirm --needed
publish:
image: 'curlimages/curl'
secrets:
- 'vieter_api_key'
commands:
# Publish the package
- 'for pkg in $(ls -1 *.pkg*); do curl -f -XPOST -T "$pkg" -H "X-API-KEY: $VIETER_API_KEY" https://arch.r8r.be/vieter/publish; done'

View File

@ -0,0 +1,18 @@
platform: 'linux/amd64'
branches: ['master']
depends_on:
- 'vc'
pipeline:
build-publish:
image: 'woodpeckerci/plugin-docker-buildx'
secrets: [ docker_username, docker_password ]
settings:
repo: chewingbever/vlang
tag: latest
dockerfile: Dockerfile.builder
platforms: [ linux/arm64/v8, linux/amd64 ]
# The build can run every time, because we should only push when there's
# actual changes
when:
event: push

View File

@ -0,0 +1,48 @@
platform: 'linux/amd64'
branches: ['master']
pipeline:
gen-vc:
# This is what the official CI uses as well
image: 'ubuntu:latest'
secrets:
- deploy_key
commands:
# Install necessary dependencies
- apt-get update -y && apt-get install openssh-client git build-essential -y
# Build the compiler
- make
# Run ssh-agent
- eval $(ssh-agent -s)
# Add ssh key
- echo "$DEPLOY_KEY" | tr -d '\r' | ssh-add -
# Create ssh dir with proper permissions
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
# Configure git credentials
- git config --global user.email 'vbot@rustybever.be'
- git config --global user.name 'vbot'
# Verify SSH keys
- ssh-keyscan git.rustybever.be > ~/.ssh/known_hosts
# The following is copied over from the official repo's CI
# https://github.com/vlang/v/blob/master/.github/workflows/gen_vc.yml
- export "COMMIT_HASH=$(git rev-parse --short HEAD)"
- export "COMMIT_MSG=$(git log -1 --oneline --pretty='%s' HEAD)"
- rm -rf vc
- git clone --depth=1 'git@git.rustybever.be:vieter/vc.git'
- rm -rf vc/v.c vc/v_win.c
- ./v -o vc/v.c -os cross cmd/v
- ./v -o vc/v_win.c -os windows -cc msvc cmd/v
- sed -i "1s/^/#define V_COMMIT_HASH \"$COMMIT_HASH\"\n/" vc/v.c
- sed -i "1s/^/#define V_COMMIT_HASH \"$COMMIT_HASH\"\n/" vc/v_win.c
# ensure the C files are over 5000 lines long, as a safety measure
- '[ $(wc -l < vc/v.c) -gt 5000 ]'
- '[ $(wc -l < vc/v_win.c) -gt 5000 ]'
- git -C vc add v.c v_win.c
- 'git -C vc commit -m "[v:master] $COMMIT_HASH - $COMMIT_MSG"'
# in case there are recent commits:
- git -C vc pull --rebase origin main
- git -C vc push
when:
event: push

View File

@ -2,6 +2,7 @@
-*Not yet released, changelog is not full*
- Introduce `isize` and `usize` types, deprecate `size_t` in favor of `usize`.
- Add `datatypes` and `datatypes.fsm` modules.
- Add `compile_error` and `compile_warn` comptime functions.
-## V 0.2.4
-*Not yet released, changelog is not full*

View File

@ -35,32 +35,35 @@ The main files are:
- Creates a parser object for each file and runs `parse()` on them.
- The correct backend is called (C, JS, native), and a binary is compiled.
2. `v/scanner` The scanner's job is to parse a list of characters and convert
2. `vlib/v/scanner` The scanner's job is to parse a list of characters and convert
them to tokens.
3. `v/token` This is simply a list of all tokens, their string values, and a
3. `vlib/v/token` This is simply a list of all tokens, their string values, and a
couple of helper functions.
4. `v/parser` The parser. It converts a list of tokens into an AST.
4. `vlib/v/parser` The parser. It converts a list of tokens into an AST.
In V, objects can be used before declaration, so unknown types are marked as
unresolved. They are resolved later in the type checker.
5. `v/table` V creates one table object that is shared by all parsers. It
5. `vlib/v/table` V creates one table object that is shared by all parsers. It
contains all types, consts, and functions, as well as several helpers to search
for objects by name, register new objects, modify types' fields, etc.
6. `v/checker` Type checker and resolver. It processes the AST and makes sure
6. `vlib/v/checker` Type checker and resolver. It processes the AST and makes sure
the types are correct. Unresolved types are resolved, type information is added
to the AST.
7. `v/gen/c` C backend. It simply walks the AST and generates C code that can be
7. `vlib/v/gen/c` C backend. It simply walks the AST and generates C code that can be
compiled with Clang, GCC, Visual Studio, and TCC.
8. `json.v` defines the json code generation. This file will be removed once V
8. `vlib/v/gen/js` JavaScript backend. It simply walks the AST and generates JS code that can be
executed on the browser or in NodeJS/Deno.
9. `vlib/v/gen/c/json.v` defines the json code generation. This file will be removed once V
supports comptime code generation, and it will be possible to do this using the
language's tools.
9. `v/gen/native` is the directory with all the machine code generation logic. It
10. `vlib/v/gen/native` is the directory with all the machine code generation logic. It
defines a set of functions that translate assembly instructions to machine code
and build the binary from scratch byte by byte. It manually builds all headers,
segments, sections, symtable, relocations, etc. Right now it only has basic
@ -90,6 +93,7 @@ making pullrequests, and you can just do normal git operations such as:
5. When finished with a feature/bugfix/change, you can:
`git checkout -b fix_alabala`
- Don't forget to keep formatting standards, run `v fmt -w YOUR_MODIFIED_FILES` before committing
6. `git push pullrequest` # (NOTE: the `pullrequest` remote was setup on step 4)
7. On GitHub's web interface, go to: https://github.com/vlang/v/pulls

33
Dockerfile.builder 100644
View File

@ -0,0 +1,33 @@
FROM alpine:3.15
ARG TARGETPLATFORM
WORKDIR /opt/vlang
ENV VVV /opt/vlang
ENV PATH /opt/vlang:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV VFLAGS -cc gcc -d dynamic_boehm
ENV V_PATH /opt/vlang/v
RUN ln -s /opt/vlang/v /usr/bin/v && \
apk --no-cache add \
git make gcc curl openssl \
musl-dev \
openssl-libs-static openssl-dev \
zlib-static bzip2-static xz-dev expat-static zstd-static lz4-static \
sqlite-static sqlite-dev \
libx11-dev glfw-dev freetype-dev \
libarchive-static libarchive-dev \
gc-dev \
diffutils
RUN git clone https://git.rustybever.be/vieter/v /opt/vlang && \
make && \
v -version
RUN if [ "$TARGETPLATFORM" = 'linux/amd64' ]; then \
wget -O /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc && \
chmod +x /usr/local/bin/mc ; \
fi
CMD ["v"]

View File

@ -1,10 +1,10 @@
FROM mstorsjo/llvm-mingw
LABEL maintainer="Vitaly Takmazov <vitalyster@gmail.com>"
LABEL maintainer="Delyan Angelov <delian66@gmail.com>"
COPY . .
RUN make
RUN ./v -os windows -o v.c cmd/v
RUN x86_64-w64-mingw32-gcc v.c -std=c99 -I ./thirdparty/stdatomic/win -w -municode -o v.exe
RUN x86_64-w64-mingw32-gcc v.c -std=c99 -w -municode -o v.exe
RUN file v.exe
CMD [ "bash" ]

View File

@ -5,7 +5,7 @@ TMPDIR ?= /tmp
VROOT ?= .
VC ?= ./vc
V ?= ./v
VCREPO ?= https://github.com/vlang/vc
VCREPO ?= https://git.rustybever.be/vieter/vc
TCCREPO ?= https://github.com/vlang/tccbin
VCFILE := v.c
@ -76,7 +76,7 @@ endif
endif
endif
.PHONY: all clean fresh_vc fresh_tcc check_for_working_tcc
.PHONY: all clean check fresh_vc fresh_tcc check_for_working_tcc
ifdef prod
VFLAGS+=-prod
@ -84,13 +84,13 @@ endif
all: latest_vc latest_tcc
ifdef WIN32
$(CC) $(CFLAGS) -std=c99 -municode -w -I ./thirdparty/stdatomic/nix -o v1.exe $(VC)/$(VCFILE) $(LDFLAGS)
$(CC) $(CFLAGS) -std=c99 -municode -w -o v1.exe $(VC)/$(VCFILE) $(LDFLAGS)
v1.exe -no-parallel -o v2.exe $(VFLAGS) cmd/v
v2.exe -o $(V) $(VFLAGS) cmd/v
del v1.exe
del v2.exe
else
$(CC) $(CFLAGS) -std=gnu99 -w -I ./thirdparty/stdatomic/nix -o v1.exe $(VC)/$(VCFILE) -lm -lpthread $(LDFLAGS)
$(CC) $(CFLAGS) -std=gnu99 -w -o v1.exe $(VC)/$(VCFILE) -lm -lpthread $(LDFLAGS)
./v1.exe -no-parallel -o v2.exe $(VFLAGS) cmd/v
./v2.exe -o $(V) $(VFLAGS) cmd/v
rm -rf v1.exe v2.exe
@ -164,3 +164,5 @@ selfcompile-static:
install:
@echo 'Please use `sudo ./v symlink` instead.'
check:
$(V) test-all

View File

@ -3,12 +3,17 @@ VFLAGS ?=
CFLAGS ?=
LDFLAGS ?=
.PHONY: all check
all:
rm -rf vc/
git clone --depth 1 --quiet https://github.com/vlang/vc
$(CC) $(CFLAGS) -std=gnu11 -w -I ./thirdparty/stdatomic/nix -o v1 vc/v.c -lm -lexecinfo -lpthread $(LDFLAGS)
git clone --depth 1 --quiet https://git.rustybever.be/vieter/vc
$(CC) $(CFLAGS) -std=gnu11 -w -o v1 vc/v.c -lm -lexecinfo -lpthread $(LDFLAGS)
./v1 -no-parallel -o v2 $(VFLAGS) cmd/v
./v2 -o v $(VFLAGS) cmd/v
rm -rf v1 v2 vc/
@echo "V has been successfully built"
./v run ./cmd/tools/detect_tcc.v
check:
./v test-all

54
PKGBUILD 100644
View File

@ -0,0 +1,54 @@
# Maintainer: Jef Roosens
# This PKGBUILD is mostly copied over from the AUR
# https://aur.archlinux.org/packages/vlang-git
pkgname=vieter-v
pkgver=0.2.2.r796.gfbc02cbc5
pkgrel=1
pkgdesc='Simple, fast, safe, compiled language for developing maintainable software'
arch=('x86_64' 'aarch64')
url='https://vlang.io'
license=('MIT')
depends=('glibc')
makedepends=('git')
optdepends=('glfw: Needed for graphics support'
'freetype2: Needed for graphics support'
'openssl: Needed for http support')
provides=('vlang')
conflicts=('v' 'vlang' 'vlang-bin')
source=('vlang::git+https://git.rustybever.be/Chewing_Bever/v')
sha256sums=('SKIP')
pkgver() {
cd "${srcdir}/vlang"
# Weekly tags are considered older than semantic tags that are older than
# them, so to prevent version resolution problems we exclude weekly tags.
git describe --long --tags --exclude "weekly*" | sed 's/^v//;s/\([^-]*-g\)/r\1/;s/-/./g'
}
build() {
cd "${srcdir}/vlang"
# We don't require optimizations when compiling the bootstrap executable and
# -O2 actually breaks `./v self` (resulting in "cgen error:"), so we empty
# CFLAGS and LDFLAGS to ensure successful compilation.
CFLAGS="" LDFLAGS="" prod=1 make
# vpm and vdoc fail to compile with "unsupported linker option" when LDFLAGS
# is set
LDFLAGS="" ./v build-tools
}
package() {
cd "${srcdir}/vlang"
install -d "$pkgdir/usr/lib/vlang" "$pkgdir/usr/share/vlang" "$pkgdir/usr/bin"
install -Dm644 LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE"
install -Dm755 v "$pkgdir/usr/lib/vlang"
cp -a cmd "$pkgdir/usr/lib/vlang/"
cp -a examples "$pkgdir/usr/share/vlang/"
cp -a thirdparty "$pkgdir/usr/lib/vlang/"
cp -a vlib "$pkgdir/usr/lib/vlang/"
cp v.mod "$pkgdir/usr/lib/vlang/"
ln -s /usr/lib/vlang/v "$pkgdir/usr/bin/v"
touch "$pkgdir/usr/lib/vlang/cmd/tools/.disable_autorecompilation"
}

View File

@ -4,11 +4,7 @@
</p>
<h1>The V Programming Language</h1>
[vlang.io](https://vlang.io) |
[Docs](https://github.com/vlang/v/blob/master/doc/docs.md) |
[Changelog](https://github.com/vlang/v/blob/master/CHANGELOG.md) |
[Speed](https://fast.vlang.io/) |
[Contributing & compiler design](https://github.com/vlang/v/blob/master/CONTRIBUTING.md)
[vlang.io](https://vlang.io) | [Docs](https://github.com/vlang/v/blob/master/doc/docs.md) | [Changelog](https://github.com/vlang/v/blob/master/CHANGELOG.md) | [Speed](https://fast.vlang.io/) | [Contributing & compiler design](https://github.com/vlang/v/blob/master/CONTRIBUTING.md)
</div>
<div align="center">

View File

@ -14,9 +14,9 @@ fn main() {
mut checksum := u64(0)
mut start_pos := 0
mut bgenerating := benchmark.start()
mut bytepile := []byte{}
mut bytepile := []u8{}
for _ in 0 .. sample_size * max_str_len {
bytepile << byte(rand.int_in_range(40, 125) or { 40 })
bytepile << u8(rand.int_in_range(40, 125) or { 40 })
}
mut str_lens := []int{}
for _ in 0 .. sample_size {
@ -30,7 +30,7 @@ fn main() {
checksum = 0
for len in str_lens {
end_pos := start_pos + len
checksum ^= wyhash.wyhash_c(unsafe { &byte(bytepile.data) + start_pos }, u64(len),
checksum ^= wyhash.wyhash_c(unsafe { &u8(bytepile.data) + start_pos }, u64(len),
1)
start_pos = end_pos
}

View File

@ -4,6 +4,7 @@ fn main() {
exit(0)
}
$if !macos {
println('
Note: `tcc` was not used, so unless you install it yourself, your backend
C compiler will be `cc`, which is usually either `clang`, `gcc` or `msvc`.
@ -13,3 +14,4 @@ compared to `tcc`. They do produce more optimised executables, but that
is done at the cost of compilation speed.
')
}
}

View File

@ -28,7 +28,8 @@ fn main() {
return
}
}
// Fetch the last commit's hash
// fetch the last commit's hash
commit := exec('git rev-parse HEAD')[..8]
if !os.exists('table.html') {
os.create('table.html')?
@ -42,13 +43,10 @@ fn main() {
return
}
}
// for i, commit in commits {
message := exec('git log --pretty=format:"%s" -n1 $commit')
// println('\n${i + 1}/$commits.len Benchmarking commit $commit "$message"')
println('\nBenchmarking commit $commit "$message"')
// Build an optimized V
// println('Checking out ${commit}...')
// exec('git checkout $commit')
// build an optimized V
println(' Building vprod...')
os.chdir(vdir)?
if os.args.contains('-noprod') {
@ -56,9 +54,11 @@ fn main() {
} else {
exec('./v -o vprod -prod -prealloc cmd/v')
}
// cache vlib modules
exec('$vdir/v wipe-cache')
exec('$vdir/v -o v2 -prod cmd/v')
// measure
diff1 := measure('$vdir/vprod $voptions -o v.c cmd/v', 'v.c')
mut tcc_path := 'tcc'
@ -71,20 +71,21 @@ fn main() {
if os.args.contains('-clang') {
tcc_path = 'clang'
}
diff2 := measure('$vdir/vprod $voptions -cc $tcc_path -o v2 cmd/v', 'v2')
diff3 := 0 // measure('$vdir/vprod -native $vdir/cmd/tools/1mil.v', 'native 1mil')
diff4 := measure('$vdir/vprod -usecache $voptions -cc clang examples/hello_world.v',
'hello.v')
vc_size := os.file_size('v.c') / 1000
// scan/parse/check/cgen
scan, parse, check, cgen, vlines := measure_steps(vdir)
// println('Building V took ${diff}ms')
commit_date := exec('git log -n1 --pretty="format:%at" $commit')
date := time.unix(commit_date.int())
//
os.chdir(fast_dir)?
mut out := os.create('table.html')?
// Place the new row on top
// place the new row on top
html_message := message.replace_each(['<', '&lt;', '>', '&gt;'])
table =
' <tr>
@ -106,7 +107,8 @@ fn main() {
table.trim_space()
out.writeln(table)?
out.close()
// Regenerate index.html
// regenerate index.html
header := os.read_file('header.html')?
footer := os.read_file('footer.html')?
mut res := os.create('index.html')?
@ -114,10 +116,8 @@ fn main() {
res.writeln(table)?
res.writeln(footer)?
res.close()
//}
// exec('git checkout master')
// os.write_file('last_commit.txt', commits[commits.len - 1]) ?
// Upload the result to github pages
// upload the result to github pages
if os.args.contains('-upload') {
println('uploading...')
os.chdir('website')?
@ -134,7 +134,7 @@ fn exec(s string) string {
return e.output.trim_right('\r\n')
}
// returns milliseconds
// measure returns milliseconds
fn measure(cmd string, description string) int {
println(' Measuring $description')
println(' Warming up...')
@ -186,7 +186,7 @@ fn measure_steps(vdir string) (int, int, int, int, int) {
cgen = line[0].int()
}
} else {
// Fetch number of V lines
// fetch number of V lines
if line[0].contains('V') && line[0].contains('source') && line[0].contains('size') {
start := line[0].index(':') or { 0 }
end := line[0].index('lines,') or { 0 }

View File

@ -19,6 +19,8 @@ pub const hide_oks = os.getenv('VTEST_HIDE_OK') == '1'
pub const fail_fast = os.getenv('VTEST_FAIL_FAST') == '1'
pub const fail_flaky = os.getenv('VTEST_FAIL_FLAKY') == '1'
pub const test_only = os.getenv('VTEST_ONLY').split_any(',')
pub const test_only_fn = os.getenv('VTEST_ONLY_FN').split_any(',')
@ -35,7 +37,6 @@ pub mut:
vroot string
vtmp_dir string
vargs string
failed bool
fail_fast bool
benchmark benchmark.Benchmark
rm_binaries bool = true
@ -286,7 +287,7 @@ pub fn (mut ts TestSession) test() {
fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
mut ts := &TestSession(p.get_shared_context())
if ts.fail_fast {
if ts.failed {
if ts.failed_cmds.len > 0 {
return pool.no_result
}
}
@ -362,7 +363,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
details := get_test_details(file)
os.setenv('VTEST_RETRY_MAX', '$details.retry', true)
for retry := 1; retry <= details.retry; retry++ {
ts.append_message(.info, ' retrying $retry/$details.retry of $relative_file ...')
ts.append_message(.info, ' [stats] retrying $retry/$details.retry of $relative_file ; known flaky: $details.flaky ...')
os.setenv('VTEST_RETRY', '$retry', true)
status = os.system(cmd)
if status == 0 {
@ -372,7 +373,12 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
}
time.sleep(500 * time.millisecond)
}
ts.failed = true
if details.flaky && !testing.fail_flaky {
ts.append_message(.info, ' *FAILURE* of the known flaky test file $relative_file is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: $details.retry .')
unsafe {
goto test_passed_system
}
}
ts.benchmark.fail()
tls_bench.fail()
ts.add_failed_cmd(cmd)
@ -388,7 +394,6 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
}
mut r := os.execute(cmd)
if r.exit_code < 0 {
ts.failed = true
ts.benchmark.fail()
tls_bench.fail()
ts.append_message(.fail, tls_bench.step_message_fail(normalised_relative_file))
@ -399,7 +404,7 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
details := get_test_details(file)
os.setenv('VTEST_RETRY_MAX', '$details.retry', true)
for retry := 1; retry <= details.retry; retry++ {
ts.append_message(.info, ' retrying $retry/$details.retry of $relative_file ...')
ts.append_message(.info, ' retrying $retry/$details.retry of $relative_file ; known flaky: $details.flaky ...')
os.setenv('VTEST_RETRY', '$retry', true)
r = os.execute(cmd)
if r.exit_code == 0 {
@ -408,7 +413,12 @@ fn worker_trunner(mut p pool.PoolProcessor, idx int, thread_id int) voidptr {
}
}
}
ts.failed = true
if details.flaky && !testing.fail_flaky {
ts.append_message(.info, ' *FAILURE* of the known flaky test file $relative_file is ignored, since VTEST_FAIL_FLAKY is 0 . Retry count: $details.retry .')
unsafe {
goto test_passed_execute
}
}
ts.benchmark.fail()
tls_bench.fail()
ending_newline := if r.output.ends_with('\n') { '\n' } else { '' }
@ -457,7 +467,7 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
// for example module import tests, or subtests, that are compiled/run by other parent tests
// in specific configurations, etc.
if fnormalised.contains('testdata/') || fnormalised.contains('modules/')
|| f.contains('preludes/') {
|| fnormalised.contains('preludes/') {
continue
}
$if windows {
@ -475,7 +485,8 @@ pub fn prepare_test_session(zargs string, folder string, oskipped []string, main
skipped << skipped_f
}
for skip_prefix in oskipped {
if f.starts_with(skip_prefix) {
skip_folder := skip_prefix + '/'
if fnormalised.starts_with(skip_folder) {
continue next_file
}
}
@ -495,7 +506,7 @@ pub fn v_build_failing_skipped(zargs string, folder string, oskipped []string, c
cb(mut session)
session.test()
eprintln(session.benchmark.total_message(finish_label))
return session.failed
return session.failed_cmds.len > 0
}
pub fn build_v_cmd_failed(cmd string) bool {
@ -562,6 +573,7 @@ pub fn setup_new_vtmp_folder() string {
pub struct TestDetails {
pub mut:
retry int
flaky bool // when flaky tests fail, the whole run is still considered successfull, unless VTEST_FAIL_FLAKY is 1
}
pub fn get_test_details(file string) TestDetails {
@ -571,6 +583,9 @@ pub fn get_test_details(file string) TestDetails {
if line.starts_with('// vtest retry:') {
res.retry = line.all_after(':').trim_space().int()
}
if line.starts_with('// vtest flaky:') {
res.flaky = line.all_after(':').trim_space().bool()
}
}
return res
}

View File

@ -24,7 +24,7 @@ fn C.cJSON_CreateNull() &C.cJSON
// fn C.cJSON_CreateNumber() &C.cJSON
// fn C.cJSON_CreateString() &C.cJSON
fn C.cJSON_CreateRaw(&byte) &C.cJSON
fn C.cJSON_CreateRaw(&u8) &C.cJSON
fn C.cJSON_IsInvalid(voidptr) bool
@ -45,13 +45,13 @@ fn C.cJSON_IsObject(voidptr) bool
fn C.cJSON_IsRaw(voidptr) bool
fn C.cJSON_AddItemToObject(voidptr, &byte, voidptr)
fn C.cJSON_AddItemToObject(voidptr, &u8, voidptr)
fn C.cJSON_AddItemToArray(voidptr, voidptr)
fn C.cJSON_Delete(voidptr)
fn C.cJSON_Print(voidptr) &byte
fn C.cJSON_Print(voidptr) &u8
[inline]
fn create_object() &C.cJSON {

View File

@ -283,7 +283,7 @@ fn (t Tree) embed_file(node ast.EmbeddedFile) &Node {
obj.add('compression_type', t.string_node(node.compression_type))
obj.add('is_compressed', t.bool_node(node.is_compressed))
obj.add('len', t.number_node(node.len))
obj.add('bytes', t.array_node_byte(node.bytes))
obj.add('bytes', t.array_node_u8(node.bytes))
return obj
}
@ -1216,7 +1216,7 @@ fn (t Tree) string_inter_literal(node ast.StringInterLiteral) &Node {
obj.add_terse('pluss', t.array_node_bool(node.pluss))
obj.add_terse('fills', t.array_node_bool(node.fills))
obj.add_terse('fmt_poss', t.array_node_position(node.fmt_poss))
obj.add_terse('fmts', t.array_node_byte(node.fmts))
obj.add_terse('fmts', t.array_node_u8(node.fmts))
obj.add_terse('need_fmts', t.array_node_bool(node.need_fmts))
obj.add('pos', t.pos(node.pos))
return obj
@ -2209,7 +2209,7 @@ fn (t Tree) array_node_int(nodes []int) &Node {
return arr
}
fn (t Tree) array_node_byte(nodes []byte) &Node {
fn (t Tree) array_node_u8(nodes []u8) &Node {
mut arr := new_array()
for node in nodes {
arr.add_item(t.number_node(node))

View File

@ -46,12 +46,12 @@ fn (context Context) footer() string {
return ')\n'
}
fn (context Context) file2v(bname string, fbytes []byte, bn_max int) string {
fn (context Context) file2v(bname string, fbytes []u8, bn_max int) string {
mut sb := strings.new_builder(1000)
bn_diff_len := bn_max - bname.len
sb.write_string('\t${bname}_len' + ' '.repeat(bn_diff_len - 4) + ' = $fbytes.len\n')
fbyte := fbytes[0]
bnmae_line := '\t$bname' + ' '.repeat(bn_diff_len) + ' = [byte($fbyte), '
bnmae_line := '\t$bname' + ' '.repeat(bn_diff_len) + ' = [u8($fbyte), '
sb.write_string(bnmae_line)
mut line_len := bnmae_line.len + 3
for i := 1; i < fbytes.len; i++ {
@ -73,7 +73,7 @@ fn (context Context) file2v(bname string, fbytes []byte, bn_max int) string {
return sb.str()
}
fn (context Context) bname_and_bytes(file string) ?(string, []byte) {
fn (context Context) bname_and_bytes(file string) ?(string, []u8) {
fname := os.file_name(file)
fname_escaped := fname.replace_each(['.', '_', '-', '_'])
byte_name := '$context.prefix$fname_escaped'.to_lower()
@ -120,7 +120,7 @@ fn main() {
if context.write_file != '' && os.file_ext(context.write_file) !in ['.vv', '.v'] {
context.write_file += '.v'
}
mut file_byte_map := map[string][]byte{}
mut file_byte_map := map[string][]u8{}
for file in real_files {
bname, fbytes := context.bname_and_bytes(file) or {
eprintln(err.msg())

View File

@ -12,7 +12,8 @@ const efolders = [
fn main() {
args_string := os.args[1..].join(' ')
params := args_string.all_before('build-examples')
skip_prefixes := efolders.map(os.real_path(os.join_path_single(vroot, it)))
skip_prefixes := efolders.map(os.real_path(os.join_path_single(vroot, it)).replace('\\',
'/'))
res := testing.v_build_failing_skipped(params, 'examples', skip_prefixes, fn (mut session testing.TestSession) {
for x in efolders {
pathsegments := x.split_any('/')

View File

@ -31,7 +31,7 @@ fn main() {
//
mut skips := []string{}
for stool in tools_in_subfolders {
skips << os.join_path(tfolder, stool)
skips << os.join_path(tfolder, stool).replace('\\', '/')
}
buildopts := args_string.all_before('build-tools')
mut session := testing.prepare_test_session(buildopts, folder, skips, main_label)
@ -43,7 +43,7 @@ fn main() {
// eprintln('> session.skip_files: $session.skip_files')
session.test()
eprintln(session.benchmark.total_message(finish_label))
if session.failed {
if session.failed_cmds.len > 0 {
exit(1)
}
//

View File

@ -160,7 +160,7 @@ fn create(args []string) {
if c.version == '' {
c.version = default_version
}
default_license := 'MIT'
default_license := os.getenv_opt('VLICENSE') or { 'MIT' }
c.license = os.input('Input your project license: ($default_license) ')
if c.license == '' {
c.license = default_license

View File

@ -303,7 +303,7 @@ fn html_highlight(code string, tb &ast.Table) string {
} else if typ == .char {
'`$tok.lit`'
} else if typ == .comment {
if tok.lit[0] == 1 { '//${tok.lit[1..]}' } else { '//$tok.lit' }
if tok.lit != '' && tok.lit[0] == 1 { '//${tok.lit[1..]}' } else { '//$tok.lit' }
} else {
tok.lit
}
@ -370,7 +370,7 @@ fn html_highlight(code string, tb &ast.Table) string {
break
}
} else {
buf.write_byte(code[i])
buf.write_u8(code[i])
i++
}
}

View File

@ -1,7 +1,13 @@
module main
const (
source_root = 'temp'
source_root = 'temp' // some const
another = int(5) //
)
const (
windowpos_undefined_mask = C.SDL_WINDOWPOS_UNDEFINED_MASK // 0x1FFF0000u
windowpos_undefined = C.SDL_WINDOWPOS_UNDEFINED //
)
Used to indicate that you don't care what the window position is.
fn funky()
funky - comment for function below

View File

@ -1,6 +1,11 @@
module main
const (
source_root = 'temp'
source_root = 'temp' // some const
another = int(5) //
)
const (
windowpos_undefined_mask = C.SDL_WINDOWPOS_UNDEFINED_MASK // 0x1FFF0000u
windowpos_undefined = C.SDL_WINDOWPOS_UNDEFINED //
)
fn funky()

View File

@ -1,5 +1,12 @@
pub const (
source_root = 'temp'
source_root = 'temp' // some const
another = int(5) //
)
// Used to indicate that you don't care what the window position is.
pub const (
windowpos_undefined_mask = C.SDL_WINDOWPOS_UNDEFINED_MASK // 0x1FFF0000u
windowpos_undefined = C.SDL_WINDOWPOS_UNDEFINED //
)
// funky - comment for function below

View File

@ -162,7 +162,11 @@ fn color_highlight(code string, tb &ast.Table) string {
lit = term.yellow('`$tok.lit`')
}
.comment {
lit = if tok.lit[0] == 1 { '//${tok.lit[1..]}' } else { '//$tok.lit' }
lit = if tok.lit != '' && tok.lit[0] == 1 {
'//${tok.lit[1..]}'
} else {
'//$tok.lit'
}
}
.keyword {
lit = term.bright_blue(tok.lit)
@ -209,16 +213,18 @@ fn color_highlight(code string, tb &ast.Table) string {
} else if
next_tok.kind in [.lcbr, .rpar, .eof, .comma, .pipe, .name, .rcbr, .assign, .key_pub, .key_mut, .pipe, .comma]
&& prev.kind in [.name, .amp, .rsbr, .key_type, .assign, .dot, .question, .rpar, .key_struct, .key_enum, .pipe, .key_interface]
&& (tok.lit[0].is_capital() || prev_prev.lit in ['C', 'JS']) {
&& ((tok.lit != '' && tok.lit[0].is_capital())
|| prev_prev.lit in ['C', 'JS']) {
tok_typ = .symbol
} else if next_tok.kind == .lpar || (!tok.lit[0].is_capital()
&& next_tok.kind == .lt && next_tok.pos == tok.pos + tok.lit.len) {
} else if next_tok.kind == .lpar
|| (!(tok.lit != '' && tok.lit[0].is_capital()) && next_tok.kind == .lt
&& next_tok.pos == tok.pos + tok.lit.len) {
tok_typ = .function
} else if next_tok.kind == .dot {
if tok.lit in ['C', 'JS'] {
tok_typ = .prefix
} else {
if tok.lit[0].is_capital() {
if tok.lit != '' && tok.lit[0].is_capital() {
tok_typ = .symbol
} else {
tok_typ = .module_
@ -271,7 +277,7 @@ fn color_highlight(code string, tb &ast.Table) string {
tok = next_tok
next_tok = s.scan()
} else {
buf.write_byte(code[i])
buf.write_u8(code[i])
i++
}
}

View File

@ -132,9 +132,9 @@ fn (vd VDoc) write_plaintext_content(contents []doc.DocNode, mut pw strings.Buil
for ex in examples {
pw.write_string(' Example: ')
mut fex := ex
if ex.index_byte(`\n`) >= 0 {
if ex.index_u8(`\n`) >= 0 {
// multi-line example
pw.write_byte(`\n`)
pw.write_u8(`\n`)
fex = indent(ex)
}
if cfg.is_color {

View File

@ -61,9 +61,7 @@ fn main() {
if term_colors {
os.setenv('VCOLORS', 'always', true)
}
if foptions.is_verbose {
eprintln('vfmt foptions: $foptions')
}
foptions.vlog('vfmt foptions: $foptions')
if foptions.is_worker {
// -worker should be added by a parent vfmt process.
// We launch a sub process for each file because
@ -109,9 +107,7 @@ fn main() {
mut worker_command_array := cli_args_no_files.clone()
worker_command_array << ['-worker', util.quote_path(fpath)]
worker_cmd := worker_command_array.join(' ')
if foptions.is_verbose {
eprintln('vfmt worker_cmd: $worker_cmd')
}
foptions.vlog('vfmt worker_cmd: $worker_cmd')
worker_result := os.execute(worker_cmd)
// Guard against a possibly crashing worker process.
if worker_result.exit_code != 0 {
@ -151,43 +147,43 @@ fn main() {
}
}
fn (foptions &FormatOptions) format_file(file string) {
fn setup_preferences_and_table() (&pref.Preferences, &ast.Table) {
table := ast.new_table()
mut prefs := pref.new_preferences()
prefs.is_fmt = true
if foptions.is_verbose {
eprintln('vfmt2 running fmt.fmt over file: $file')
prefs.skip_warnings = true
return prefs, table
}
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
fn (foptions &FormatOptions) vlog(msg string) {
if foptions.is_verbose {
eprintln(msg)
}
}
fn (foptions &FormatOptions) format_file(file string) {
foptions.vlog('vfmt2 running fmt.fmt over file: $file')
prefs, table := setup_preferences_and_table()
file_ast := parser.parse_file(file, table, .parse_comments, prefs)
// checker.check(file_ast)
// checker.new_checker(table, prefs).check(file_ast)
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug)
file_name := os.file_name(file)
ulid := rand.ulid()
vfmt_output_path := os.join_path(vtmp_folder, 'vfmt_${ulid}_$file_name')
os.write_file(vfmt_output_path, formatted_content) or { panic(err) }
if foptions.is_verbose {
eprintln('fmt.fmt worked and $formatted_content.len bytes were written to $vfmt_output_path .')
}
foptions.vlog('fmt.fmt worked and $formatted_content.len bytes were written to $vfmt_output_path .')
eprintln('$formatted_file_token$vfmt_output_path')
}
fn (foptions &FormatOptions) format_pipe() {
mut prefs := pref.new_preferences()
prefs.is_fmt = true
if foptions.is_verbose {
eprintln('vfmt2 running fmt.fmt over stdin')
}
foptions.vlog('vfmt2 running fmt.fmt over stdin')
prefs, table := setup_preferences_and_table()
input_text := os.get_raw_lines_joined()
table := ast.new_table()
// checker := checker.new_checker(table, prefs)
file_ast := parser.parse_text(input_text, '', table, .parse_comments, prefs)
// checker.check(file_ast)
// checker.new_checker(table, prefs).check(file_ast)
formatted_content := fmt.fmt(file_ast, table, prefs, foptions.is_debug)
print(formatted_content)
if foptions.is_verbose {
eprintln('fmt.fmt worked and $formatted_content.len bytes were written to stdout.')
}
foptions.vlog('fmt.fmt worked and $formatted_content.len bytes were written to stdout.')
}
fn print_compiler_options(compiler_params &pref.Preferences) {
@ -234,9 +230,7 @@ fn (mut foptions FormatOptions) post_process_file(file string, formatted_file_pa
return
}
diff_cmd := foptions.find_diff_cmd()
if foptions.is_verbose {
eprintln('Using diff command: $diff_cmd')
}
foptions.vlog('Using diff command: $diff_cmd')
diff := diff.color_compare_files(diff_cmd, file, formatted_file_path)
if diff.len > 0 {
println(diff)

View File

@ -5,8 +5,8 @@ import os
import flag
const (
tool_name = os.file_name(os.executable())
tool_version = '0.0.3'
tool_name = 'v missdoc'
tool_version = '0.0.4'
tool_description = 'Prints all V functions in .v files under PATH/, that do not yet have documentation comments.'
work_dir_prefix = normalise_path(os.real_path(os.wd_at_startup) + '/')
)

View File

@ -584,17 +584,22 @@ fn get_all_modules() []string {
mut read_len := 0
mut modules := []string{}
for read_len < s.len {
mut start_token := '<a href="/mod'
mut start_token := "<a href='/mod"
end_token := '</a>'
// get the start index of the module entry
mut start_index := s.index_after(start_token, read_len)
if start_index == -1 {
start_token = '<a href="/mod'
start_index = s.index_after(start_token, read_len)
if start_index == -1 {
break
}
}
// get the index of the end of anchor (a) opening tag
// we use the previous start_index to make sure we are getting a module and not just a random 'a' tag
start_token = '">'
start_token = '>'
start_index = s.index_after(start_token, start_index) + start_token.len
// get the index of the end of module entry
end_index := s.index_after(end_token, start_index)
if end_index == -1 {

View File

@ -49,6 +49,12 @@ enum RunCommandKind {
const expect_nothing = '<nothing>'
const starts_with_nothing = '<nothing>'
const ends_with_nothing = '<nothing>'
const contains_nothing = '<nothing>'
struct Command {
mut:
line string
@ -59,6 +65,9 @@ mut:
rmfile string
runcmd RunCommandKind = .system
expect string = expect_nothing
starts_with string = starts_with_nothing
ends_with string = ends_with_nothing
contains string = contains_nothing
output string
}
@ -81,12 +90,32 @@ fn get_all_commands() []Command {
runcmd: .execute
expect: 'Hello, World!\n'
}
if os.getenv('V_CI_MUSL').len == 0 {
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'
runcmd: .execute
expect: 'Hello, World!\n'
}
}
}
}
res << Command{
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
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'
}
res << Command{
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 -` .'
@ -210,9 +239,8 @@ fn get_all_commands() []Command {
rmfile: 'examples/tetris/tetris'
}
$if macos || linux {
ipath := '$vroot/thirdparty/stdatomic/nix'
res << Command{
line: '$vexe -o v.c cmd/v && cc -Werror -I ${os.quoted_path(ipath)} v.c -lpthread -lm && rm -rf a.out'
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'
@ -241,23 +269,56 @@ fn (mut cmd Command) run() {
spent := sw.elapsed().milliseconds()
//
mut is_failed := false
mut is_failed_expected := false
mut is_failed_starts_with := false
mut is_failed_ends_with := false
mut is_failed_contains := false
if cmd.ecode != 0 {
is_failed = true
}
if cmd.expect != expect_nothing {
if cmd.output != cmd.expect {
is_failed = true
is_failed_expected = true
}
}
if cmd.starts_with != starts_with_nothing {
if !cmd.output.starts_with(cmd.starts_with) {
is_failed = true
is_failed_starts_with = true
}
}
if cmd.ends_with != ends_with_nothing {
if !cmd.output.ends_with(cmd.ends_with) {
is_failed = true
is_failed_ends_with = true
}
}
if cmd.contains != contains_nothing {
if !cmd.output.contains(cmd.contains) {
is_failed = true
is_failed_contains = true
}
}
//
run_label := if is_failed { term.failed('FAILED') } else { term_highlight('OK') }
println('> Running: "$cmd.line" took: $spent ms ... $run_label')
//
if is_failed && cmd.expect != expect_nothing {
if cmd.output != cmd.expect {
if is_failed && is_failed_expected {
eprintln('> expected:\n$cmd.expect')
eprintln('> output:\n$cmd.output')
}
if is_failed && is_failed_starts_with {
eprintln('> expected to start with:\n$cmd.starts_with')
eprintln('> output:\n${cmd.output#[..cmd.starts_with.len]}')
}
if is_failed && is_failed_ends_with {
eprintln('> expected to end with:\n$cmd.ends_with')
eprintln('> output:\n${cmd.output#[-cmd.starts_with.len..]}')
}
if is_failed && is_failed_contains {
eprintln('> expected to contain:\n$cmd.contains')
eprintln('> output:\n$cmd.output')
}
if vtest_nocleanup {
return

View File

@ -8,6 +8,8 @@ const github_job = os.getenv('GITHUB_JOB')
const (
skip_test_files = [
'cmd/tools/vdoc/html_tag_escape_test.v', /* can't locate local module: markdown */
'cmd/tools/vdoc/tests/vdoc_file_test.v', /* fails on Windows; order of output is not as expected */
'vlib/context/onecontext/onecontext_test.v',
'vlib/context/deadline_test.v' /* sometimes blocks */,
'vlib/mysql/mysql_orm_test.v' /* mysql not installed */,
@ -45,6 +47,7 @@ const (
'vlib/sqlite/sqlite_orm_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/orm_sub_array_struct_test.v',
'vlib/v/tests/orm_joined_tables_select_test.v',
'vlib/v/tests/sql_statement_inside_fn_call_test.v',
'vlib/vweb/tests/vweb_test.v',
'vlib/vweb/request_test.v',
@ -85,6 +88,7 @@ const (
'vlib/orm/orm_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/orm_sub_array_struct_test.v',
'vlib/v/tests/orm_joined_tables_select_test.v',
'vlib/v/tests/sql_statement_inside_fn_call_test.v',
'vlib/clipboard/clipboard_test.v',
'vlib/vweb/tests/vweb_test.v',
@ -112,8 +116,7 @@ const (
'vlib/context/value_test.v',
'vlib/orm/orm_test.v',
'vlib/v/tests/orm_sub_struct_test.v',
'vlib/v/tests/closure_test.v',
'vlib/v/tests/closure_generator_test.v',
'vlib/v/tests/orm_joined_tables_select_test.v',
'vlib/net/websocket/ws_test.v',
'vlib/net/unix/unix_test.v',
'vlib/net/unix/use_net_and_net_unix_together_test.v',
@ -139,7 +142,6 @@ const (
'do_not_remove',
]
skip_on_arm64 = [
'vlib/v/tests/closure_generator_test.v',
'do_not_remove',
]
skip_on_non_amd64_or_arm64 = [
@ -167,6 +169,7 @@ fn main() {
cmd_prefix := args_string.all_before('test-self')
title := 'testing vlib'
mut all_test_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.v')
all_test_files << os.walk_ext(os.join_path(vroot, 'cmd'), '_test.v')
test_js_files := os.walk_ext(os.join_path(vroot, 'vlib'), '_test.js.v')
all_test_files << test_js_files
testing.eheader(title)

View File

@ -69,7 +69,7 @@ fn main() {
testing.header('Testing...')
ts.test()
println(ts.benchmark.total_message('all V _test.v files'))
if ts.failed {
if ts.failed_cmds.len > 0 {
exit(1)
}
}

View File

@ -34,13 +34,19 @@ fn main() {
// println(v_hash)
// println(current_hash)
if v_hash == current_hash {
println('V is already updated.')
app.show_current_v_version()
return
}
$if windows {
app.backup('cmd/tools/vup.exe')
}
app.recompile_v()
if !app.recompile_v() {
app.show_current_v_version()
eprintln('Recompiling V *failed*.')
eprintln('Try running `$get_make_cmd_name()` .')
exit(1)
}
app.recompile_vup()
app.show_current_v_version()
}
@ -66,7 +72,7 @@ fn (app App) update_from_master() {
}
}
fn (app App) recompile_v() {
fn (app App) recompile_v() bool {
// Note: app.vexe is more reliable than just v (which may be a symlink)
opts := if app.is_prod { '-prod' } else { '' }
vself := '${os.quoted_path(app.vexe)} $opts self'
@ -74,35 +80,35 @@ fn (app App) recompile_v() {
self_result := os.execute(vself)
if self_result.exit_code == 0 {
println(self_result.output.trim_space())
return
return true
} else {
app.vprintln('`$vself` failed, running `make`...')
app.vprintln(self_result.output.trim_space())
}
app.make(vself)
return app.make(vself)
}
fn (app App) recompile_vup() {
fn (app App) recompile_vup() bool {
vup_result := os.execute('${os.quoted_path(app.vexe)} -g cmd/tools/vup.v')
if vup_result.exit_code != 0 {
eprintln('recompiling vup.v failed:')
eprintln(vup_result.output)
return false
}
return true
}
fn (app App) make(vself string) {
mut make := 'make'
$if windows {
make = 'make.bat'
}
fn (app App) make(vself string) bool {
make := get_make_cmd_name()
make_result := os.execute(make)
if make_result.exit_code != 0 {
eprintln('> $make failed:')
eprintln('> make output:')
eprintln(make_result.output)
return
return false
}
app.vprintln(make_result.output)
return true
}
fn (app App) show_current_v_version() {
@ -116,8 +122,7 @@ fn (app App) show_current_v_version() {
vversion += ', timestamp: ' + latest_v_commit_time.output.trim_space()
}
}
println('Current V version:')
println(vversion)
println('Current V version: $vversion')
}
}
@ -162,3 +167,11 @@ fn (app App) get_git() {
eprintln("error: Install `git` using your system's package manager")
}
}
fn get_make_cmd_name() string {
$if windows {
return 'make.bat'
} $else {
return 'make'
}
}

View File

@ -1,2 +1,2 @@
cmd/tools/vvet/tests/array_init_one_val.vv:2: error: Use `var == value` instead of `var in [value]`
NB: You can run `v fmt -w file.v` to fix these errors automatically
Note: You can run `v fmt -w file.v` to fix these errors automatically

View File

@ -3,4 +3,4 @@ cmd/tools/vvet/tests/indent_with_space.vv:10: error: Looks like you are using sp
cmd/tools/vvet/tests/indent_with_space.vv:17: error: Looks like you are using spaces for indentation.
cmd/tools/vvet/tests/indent_with_space.vv:20: error: Looks like you are using spaces for indentation.
cmd/tools/vvet/tests/indent_with_space.vv:22: error: Looks like you are using spaces for indentation.
NB: You can run `v fmt -w file.v` to fix these errors automatically
Note: You can run `v fmt -w file.v` to fix these errors automatically

View File

@ -0,0 +1,6 @@
// Some header comment
// read_response is a carefully constructed comment.
// read_response_body. <-- this would earlier trigger a false
// postive.
pub fn read_response() ?(string, string) {}

View File

@ -1,2 +1,2 @@
cmd/tools/vvet/tests/parens_space_a.vv:1: error: Looks like you are adding a space after `(`
NB: You can run `v fmt -w file.v` to fix these errors automatically
Note: You can run `v fmt -w file.v` to fix these errors automatically

View File

@ -1,2 +1,2 @@
cmd/tools/vvet/tests/parens_space_b.vv:1: error: Looks like you are adding a space before `)`
NB: You can run `v fmt -w file.v` to fix these errors automatically
Note: You can run `v fmt -w file.v` to fix these errors automatically

View File

@ -25,6 +25,7 @@ struct Options {
is_verbose bool
show_warnings bool
use_color bool
doc_private_fns_too bool
}
const term_colors = term.can_show_color_on_stderr()
@ -38,6 +39,7 @@ fn main() {
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)
doc_private_fns_too: '-p' in vet_options
}
}
mut paths := cmdline.only_non_options(vet_options)
@ -110,11 +112,26 @@ fn (mut vt Vet) vet_file(path string) {
// vet_line vets the contents of `line` from `vet.file`.
fn (mut vt Vet) vet_line(lines []string, line string, lnumber int) {
// Vet public functions
if line.starts_with('pub fn') || (line.starts_with('fn ') && !(line.starts_with('fn C.')
|| line.starts_with('fn main'))) {
// Scan function declarations for missing documentation
vt.vet_fn_documentation(lines, line, lnumber)
}
// vet_fn_documentation ensures that functions are documented
fn (mut vt Vet) vet_fn_documentation(lines []string, line string, lnumber int) {
if line.starts_with('fn C.') {
return
}
is_pub_fn := line.starts_with('pub fn ')
is_fn := is_pub_fn || line.starts_with('fn ')
if !is_fn {
return
}
if line.starts_with('fn main') {
return
}
if !(is_pub_fn || vt.opt.doc_private_fns_too) {
return
}
// Scan function declarations for missing documentation
if lnumber > 0 {
collect_tags := fn (line string) []string {
mut cleaned := line.all_before('/')
@ -158,28 +175,28 @@ fn (mut vt Vet) vet_line(lines []string, line string, lnumber int) {
}
if grab {
clean_line := line.all_before_last('{').trim(' ')
if is_pub_fn {
vt.warn('Function documentation seems to be missing for "$clean_line".',
lnumber, .doc)
}
}
} else {
fn_name := ident_fn_name(line)
mut grab := true
for j := lnumber - 1; j >= 0; j-- {
mut prev_prev_line := ''
if j - 1 >= 0 {
prev_prev_line = lines[j - 1]
}
prev_line := lines[j]
if prev_line.contains('}') { // We've looked back to the above scope, stop here
break
} else if prev_line.starts_with('// $fn_name ') {
grab = false
break
} else if prev_line.starts_with('// $fn_name') {
} else if prev_line.starts_with('// $fn_name') && !prev_prev_line.starts_with('//') {
grab = false
if is_pub_fn {
clean_line := line.all_before_last('{').trim(' ')
vt.warn('The documentation for "$clean_line" seems incomplete.',
lnumber, .doc)
}
vt.warn('The documentation for "$clean_line" seems incomplete.', lnumber,
.doc)
break
} else if prev_line.starts_with('[') {
tags << collect_tags(prev_line)
@ -190,15 +207,12 @@ fn (mut vt Vet) vet_line(lines []string, line string, lnumber int) {
}
if grab {
clean_line := line.all_before_last('{').trim(' ')
if is_pub_fn {
vt.warn('A function name is missing from the documentation of "$clean_line".',
lnumber, .doc)
}
}
}
}
}
}
fn (vt &Vet) vprintln(s string) {
if !vt.opt.is_verbose {

View File

@ -267,3 +267,14 @@ see also `v help build`.
Call print_backtrace() after an assertion failure. Note that
backtraces are not implemented yet on all combinations of
platform/compiler.
-thread-stack-size 4194304
Set the thread stack size to 4MB. Use multiples of 4096.
The default is 8MB, which is enough for compiling V programs, with deeply
nested expressions (~40 levels).
It may need to be increased, if you are getting stack overflow errors for
deeply recursive programs like some of the stages of the V compiler itself,
that use relatively few threads.
It may be decreased, to reduce the memory footprint of programs that launch
hundreds/thousands of threads, but where each of the threads does not need
a big stack.

View File

@ -0,0 +1,16 @@
v missdoc 0.0.4
-----------------------------------------------
Usage: v missdoc [options] PATH [PATH]...
Description: Prints all V functions in .v files under PATH/, that do not yet have documentation comments.
Options:
-h, --help Show this help text.
-t, --tags Also print function tags if any is found.
-d, --deprecated Include deprecated functions in output.
-p, --private Include private functions in output.
--js Include JavaScript functions in output.
-n, --no-line-numbers Exclude line numbers in output.
-e, --exclude <multiple strings>
-r, --relative-paths Use relative paths in output.

View File

@ -14,5 +14,8 @@ Options:
-v, -verbose
Enable verbose logging.
-p
Report private functions with missing documentation too (by default, only the `pub fn` functions will be reported).
-force
(NB: vet development only!) Do not skip the vet regression tests.

View File

@ -28,6 +28,7 @@ const (
'doctor',
'fmt',
'gret',
'missdoc',
'repl',
'self',
'setup-freetype',

View File

@ -1,5 +1,7 @@
# V Documentation
(See https://modules.vlang.io/ for documentation of V's standard library)
## Introduction
V is a statically typed compiled programming language designed for building maintainable software.
@ -434,7 +436,7 @@ bool
string
i8 i16 int i64 i128 (soon)
byte u16 u32 u64 u128 (soon)
u8 u16 u32 u64 u128 (soon)
rune // represents a Unicode code point
@ -460,7 +462,7 @@ These are the allowed possibilities:
↘ ↘
f32 → f64
↗ ↗
byte → u16 → u32 → u64 ⬎
u8 → u16 → u32 → u64 ⬎
↘ ↘ ↘ ptr
i8 → i16 → int → i64 ⬏
```
@ -490,7 +492,7 @@ d := b + x // d is of type `f64` - automatic promotion of `x`'s value
```v nofmt
name := 'Bob'
assert name.len == 3 // will print 3
assert name[0] == byte(66) // indexing gives a byte, byte(66) == `B`
assert name[0] == u8(66) // indexing gives a byte, u8(66) == `B`
assert name[1..3] == 'ob' // slicing gives a string 'ob'
// escape codes
@ -499,7 +501,7 @@ assert windows_newline.len == 2
// arbitrary bytes can be directly specified using `\x##` notation where `#` is
// a hex digit aardvark_str := '\x61ardvark' assert aardvark_str == 'aardvark'
assert '\xc0'[0] == byte(0xc0)
assert '\xc0'[0] == u8(0xc0)
// or using octal escape `\###` notation where `#` is an octal digit
aardvark_str2 := '\141ardvark'
@ -518,7 +520,7 @@ In V, a string is a read-only array of bytes. All Unicode characters are encoded
s := 'hello 🌎' // emoji takes 4 bytes
assert s.len == 10
arr := s.bytes() // convert `string` to `[]byte`
arr := s.bytes() // convert `string` to `[]u8`
assert arr.len == 10
s2 := arr.bytestr() // convert `[]byte` to `string`
@ -692,7 +694,7 @@ A `rune` can be converted to UTF-8 bytes by using the `.bytes()` method.
```v
rocket := `🚀`
assert rocket.bytes() == [byte(0xf0), 0x9f, 0x9a, 0x80]
assert rocket.bytes() == [u8(0xf0), 0x9f, 0x9a, 0x80]
```
Hex, Unicode, and Octal escape sequences also work in a `rune` literal:
@ -704,9 +706,9 @@ assert `\u0061` == `a`
// multibyte literals work too
assert `\u2605` == `★`
assert `\u2605`.bytes() == [byte(0xe2), 0x98, 0x85]
assert `\xe2\x98\x85`.bytes() == [byte(0xe2), 0x98, 0x85]
assert `\342\230\205`.bytes() == [byte(0xe2), 0x98, 0x85]
assert `\u2605`.bytes() == [u8(0xe2), 0x98, 0x85]
assert `\xe2\x98\x85`.bytes() == [u8(0xe2), 0x98, 0x85]
assert `\342\230\205`.bytes() == [u8(0xe2), 0x98, 0x85]
```
Note that `rune` literals use the same escape syntax as strings, but they can only hold one unicode
@ -763,7 +765,7 @@ If you want a different type of integer, you can use casting:
```v
a := i64(123)
b := byte(42)
b := u8(42)
c := i16(12345)
```
@ -854,7 +856,7 @@ The type of an array is determined by the first element:
* `[1, 2, 3]` is an array of ints (`[]int`).
* `['a', 'b']` is an array of strings (`[]string`).
The user can explicitly specify the type for the first element: `[byte(16), 32, 64, 128]`.
The user can explicitly specify the type for the first element: `[u8(16), 32, 64, 128]`.
V arrays are homogeneous (all elements must have the same type).
This means that code like `[1, 'a']` will not compile.
@ -2420,9 +2422,6 @@ V supports closures too.
This means that anonymous functions can inherit variables from the scope they were created in.
They must do so explicitly by listing all variables that are inherited.
> Warning: currently works on Unix-based, x64 architectures only.
Some work is in progress to make closures work on Windows, then other architectures.
```v oksyntax
my_int := 1
my_closure := fn [my_int] () {
@ -5432,9 +5431,6 @@ numbers: [1, 2, 3]
3
```
#### `$env`
```v
@ -5450,6 +5446,34 @@ V can bring in values at compile time from environment variables.
`$env('ENV_VAR')` can also be used in top-level `#flag` and `#include` statements:
`#flag linux -I $env('JAVA_HOME')/include`.
#### `$compile_error` and `$compile_warn`
These two comptime functions are very useful for displaying custom errors/warnings during
compile time.
Both receive as their only argument a string literal that contains the message to display:
```v failcompile nofmt
// x.v
module main
$if linux {
$compile_error('Linux is not supported')
}
fn main() {
}
$ v run x.v
x.v:4:5: error: Linux is not supported
2 |
3 | $if linux {
4 | $compile_error('Linux is not supported')
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5 | }
6 |
```
### Environment specific files
If a file has an environment-specific suffix, it will only be compiled for that environment.
@ -6024,7 +6048,7 @@ a nested loop, and those do not risk violating memory-safety.
## Appendix I: Keywords
V has 41 reserved keywords (3 are literals):
V has 42 reserved keywords (3 are literals):
```v ignore
as
@ -6036,7 +6060,6 @@ const
continue
defer
else
embed
enum
false
fn
@ -6048,6 +6071,7 @@ import
in
interface
is
isreftype
lock
match
module

View File

@ -556,11 +556,11 @@ fn (mut app App) set_theme(idx int) {
}
fn (mut app App) resize() {
mut s := gg.dpi_scale()
mut s := app.gg.scale
if s == 0.0 {
s = 1.0
}
window_size := gg.window_size()
window_size := app.gg.window_size()
w := window_size.width
h := window_size.height
m := f32(math.min(w, h))

View File

@ -32,8 +32,7 @@ const (
struct App {
minutes_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw,
tp +
1 * th, center - tw, tp + 1 * th]
tp + 1 * th, center - tw, tp + 1 * th]
hours_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw, tp + 2 * th,
center - tw, tp + 2 * th]
hours3_tic []f32 = [f32(center - tw), tp, center + tw, tp, center + tw, tp, center + tw, tp + 3 * th,

View File

@ -22,7 +22,7 @@ fn main() {
mut a := i64(0)
mut b := i64(0)
mut c := i64(1)
println(a + c + c)
println(a + b + c)
for _ in 0 .. stop {
// Set a and b to the next term
a = b

View File

@ -25,7 +25,7 @@ fn on_frame(mut app App) {
for mut frame in app.frames {
for mut rocket in frame {
if !rocket.exploded {
rocket.color.a = byte(f32_max(rocket.color.a - 8, 0))
rocket.color.a = u8(f32_max(rocket.color.a - 8, 0))
rocket.draw(mut app.gg)
}
}

View File

@ -5,8 +5,8 @@ import rand
pub fn random_color() gx.Color {
return gx.Color{
r: rand.byte()
g: rand.byte()
b: rand.byte()
r: rand.u8()
g: rand.u8()
b: rand.u8()
}
}

View File

@ -19,7 +19,7 @@ pub fn (particle Particle) draw(mut ctx gg.Context) {
pub fn (mut particle Particle) tick(mut rocket Rocket, mut ctx gg.Context) {
particle.lifespan -= get_params().age_rate
particle.color.a = byte(particle.lifespan)
particle.color.a = u8(particle.lifespan)
if particle.lifespan <= 0 {
rocket.dead = true

View File

@ -1,3 +1,18 @@
fn main() {
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('The shortest path from node A to node F is: $path')
assert path == ['A', 'C', 'F']
}
// Breadth-First Search (BFS) allows you to find the shortest distance between two nodes in the graph.
fn breadth_first_search_path(graph map[string][]string, vertex string, target string) []string {
mut path := []string{}
@ -24,18 +39,3 @@ fn breadth_first_search_path(graph map[string][]string, vertex string, target st
}
return path
}
fn main() {
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('The shortest path from node A to node F is: $path')
assert path == ['A', 'C', 'F']
}

View File

@ -0,0 +1,92 @@
// Author: ccs
// I follow literally code in C, done many years ago
fn main() {
// Adjacency matrix as a map
graph := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['B', 'F']
'F': ['C', 'E']
}
println('Graph: $graph')
path := breadth_first_search_path(graph, 'A', 'F')
println('\n The shortest path from node A to node F is: $path.reverse()')
}
// Breadth-First Search (BFS) allows you to find the shortest distance between two nodes in the graph.
fn breadth_first_search_path(graph map[string][]string, start string, target string) []string {
mut path := []string{} // ONE PATH with SUCCESS = array
mut queue := []string{} // a queue ... many paths
// all_nodes := graph.keys() // get a key of this map
n_nodes := graph.len // numbers of nodes of this graph
// a map to store all the nodes visited to avoid cycles
// start all them with False, not visited yet
mut visited := a_map_nodes_bool(n_nodes) // a map fully
// false ==> not visited yet: {'A': false, 'B': false, 'C': false, 'D': false, 'E': false}
queue << start // first arrival
for queue.len != 0 {
mut node := departure(mut queue) // get the front node and remove it
if visited[node] == false { // check if this node is already visited
// if no ... test it searchinf for a final node
visited[node] = true // means: visit this node
if node == target {
path = build_path_reverse(graph, start, node, visited)
return path
}
// Expansion of node removed from queue
print('\n Expansion of node $node (true/false): ${graph[node]}')
// take all nodes from the node
for vertex in graph[node] { // println("\n ...${vertex}")
// not explored yet
if visited[vertex] == false {
queue << vertex
}
}
print('\n QUEUE: $queue (only not visited) \n Visited: $visited')
}
}
path = ['Path not found, problem in the Graph, start or end nodes! ']
return path
}
// Creating a map for VISITED nodes ...
// starting by false ===> means this node was not visited yet
fn a_map_nodes_bool(size int) map[string]bool {
mut my_map := map[string]bool{} // look this map ...
base := u8(65)
mut key := base.ascii_str()
for i in 0 .. size {
key = u8(base + i).ascii_str()
my_map[key] = false
}
return my_map
}
// classical removing of a node from the start of a queue
fn departure(mut queue []string) string {
mut x := queue[0]
queue.delete(0)
return x
}
// Based in the current node that is final, search for its parent, already visited, up to the root or start node
fn build_path_reverse(graph map[string][]string, start string, final string, visited map[string]bool) []string {
print('\n\n Nodes visited (true) or no (false): $visited')
array_of_nodes := graph.keys()
mut current := final
mut path := []string{}
path << current
for (current != start) {
for i in array_of_nodes {
if (current in graph[i]) && (visited[i] == true) {
current = i
break // the first ocurrence is enough
}
}
path << current // update the path tracked
}
return path
}

View File

@ -0,0 +1,103 @@
// Author: ccs
// I follow literally code in C, done many years ago
fn main() {
// Adjacency matrix as a map
// Example 01
graph_01 := {
'A': ['B', 'C']
'B': ['A', 'D', 'E']
'C': ['A', 'F']
'D': ['B']
'E': ['F', 'B', 'F']
'F': ['C', 'E']
}
// Example 02
graph_02 := {
'A': ['B', 'C', 'D']
'B': ['E']
'C': ['F']
'D': ['E']
'E': ['H']
'F': ['H']
'G': ['H']
'H': ['E', 'F', 'G']
}
// println('Graph: $graph')
path_01 := depth_first_search_path(graph_01, 'A', 'F')
println('\n Graph_01: a first path from node A to node F is: $path_01.reverse()')
path_02 := depth_first_search_path(graph_02, 'A', 'H')
println('\n Graph_02: a first path from node A to node F is: $path_02.reverse()')
}
// Depth-First Search (BFS) allows you to find a path between two nodes in the graph.
fn depth_first_search_path(graph map[string][]string, start string, target string) []string {
mut path := []string{} // ONE PATH with SUCCESS = array
mut stack := []string{} // a stack ... many nodes
// all_nodes := graph.keys() // get a key of this map
n_nodes := graph.len // numbers of nodes of this graph
mut visited := a_map_nodes_bool(n_nodes) // a map fully
// false ... not visited yet: {'A': false, 'B': false, 'C': false, 'D': false, 'E': false}
stack << start // first push on the stack
for stack.len > 0 {
mut node := stack.pop() // get the top node and remove it from the stack
// check if this node is already visited
if visited[node] == false {
// if no ... test it searchin for a final node
visited[node] = true // means: node visited
if node == target {
path = build_path_reverse(graph, start, node, visited)
return path
}
// Exploring of node removed from stack and add its relatives
print('\n Exploring of node $node (true/false): ${graph[node]}')
// graph[node].reverse() take a classical choice for DFS
// at most os left in this case.
// use vertex in graph[node] the choice is right
// take all nodes from the node
for vertex in graph[node].reverse() {
// println("\n ...${vertex}")
// not explored yet
if visited[vertex] == false {
stack << vertex
}
}
print('\n Stack: $stack (only not visited) \n Visited: $visited')
}
}
path = ['Path not found, problem in the Graph, start or end nodes! ']
return path
}
// Creating a map for nodes not VISITED visited ...
// starting by false ===> means this node was not visited yet
fn a_map_nodes_bool(size int) map[string]bool {
mut my_map := map[string]bool{} // look this map ...
for i in 0 .. size {
my_map[u8(65 + i).ascii_str()] = false
}
return my_map
}
// Based in the current node that is final, search for his parent, that is already visited, up to the root or start node
fn build_path_reverse(graph map[string][]string, start string, final string, visited map[string]bool) []string {
print('\n\n Nodes visited (true) or no (false): $visited')
array_of_nodes := graph.keys()
mut current := final
mut path := []string{}
path << current
for current != start {
for i in array_of_nodes {
if (current in graph[i]) && (visited[i] == true) {
current = i
break // the first ocurrence is enough
}
}
path << current // updating the path tracked
}
return path
}

View File

@ -0,0 +1,90 @@
// https://en.wikipedia.org/wiki/Topological_sorting
// A DFS RECURSIVE ALGORITHM ....
// An alternative algorithm for topological sorting is based on depth-first search. The algorithm loops through each node of the graph, in an arbitrary order, initiating a depth-first search that terminates when it hits any node that has already been visited since the beginning
// of the topological sort or the node has no outgoing edges (i.e. a leaf node)
// Discussion: https://www.gatevidyalay.com/topological-sort-topological-sorting/
// $ v run dfs_topological_ordering.v
// Author: CCS
// THE DFS RECURSIVE .... classical searchig for leaves nodes
// the arguments are used in the function to avoid global variables....
fn dfs_recursive(u string, mut visited map[string]bool, graph map[string][]string, mut top_sorting []string) {
print(' Visiting: $u -> ')
visited[u] = true
for v in graph[u] {
if visited[v] == false {
dfs_recursive(v, mut visited, graph, mut top_sorting)
}
}
top_sorting << u
}
// Creating aa map to initialize with of visited nodes .... all with false in the init
// so these nodes are NOT VISITED YET
fn visited_init(a_graph map[string][]string) map[string]bool {
mut array_of_keys := a_graph.keys() // get all keys of this map
mut temp := map[string]bool{} // attention in these initializations with maps
for i in array_of_keys {
temp[i] = false
}
return temp
}
// attention here a map STRING ---> ONE BOOLEAN ... not a string
fn main() {
// A map illustration to use in a graph
// the graph: adjacency matrix
graph_01 := {
'A': ['C', 'B']
'B': ['D']
'C': ['D']
'D': []
}
graph_02 := {
'A': ['B', 'C', 'D']
'B': ['E']
'C': ['F']
'D': ['G']
'E': ['H']
'F': ['H']
'G': ['H']
'H': [] // no cycles
}
// from: https://en.wikipedia.org/wiki/Topological_sorting
graph_03 := {
'5': ['11']
'7': ['11', '8']
'3': ['8', '10']
'11': ['2', '9', '10']
'8': ['9']
'2': []
'9': []
'10': []
}
mut graph := map[string][]string{} // the graph: adjacency matrix
for index, g_value in [graph_01, graph_02, graph_03] {
println('Topological sorting for the graph $index using a DFS recursive')
graph = g_value.clone() // graphs_sample[g].clone() // choice your SAMPLE
// mut n_nodes := graph.len
mut visited := visited_init(graph) // a map with nodes not visited
// mut start := (graph.keys()).first() // arbitrary, any node if you wish
mut top_sorting := []string{}
// advantages of map ... getting all nodes
for i in graph.keys() {
if visited[i] != true {
dfs_recursive(i, mut visited, graph, mut top_sorting)
}
}
print('\n A topological sorting of graph $index : ')
// println(g_value)
println(top_sorting.reverse())
println('')
} // End of for
}

View File

@ -0,0 +1,146 @@
// The idea of this algorithm follow :
// https://www.gatevidyalay.com/topological-sort-topological-sorting/ (GREEDY)
// (no cycles are detected)
// https://en.wikipedia.org/wiki/Topological_sorting ... just the input data
// and the Kahn algorithm
// Author: CCS
// the idea is rude: https://www.gatevidyalay.com/topological-sort-topological-sorting/
fn topog_sort_greedy(graph map[string][]string) []string {
n_nodes := graph.len // numbers of nodes of this graph
mut top_order := []string{} // a vector with sequence of nodes visited
mut count := 0
/*
IDEA ( a greedy algorythm ):
1. choose allways the node with smallest input degree
2. visit it
3. put it in the output vector
4. remove it from graph
5. update the graph (a new graph)
6. find a new vector degree
7. until all nodes has been visited
Back to step 1 (used the variable count)
Maybe it seems the Kahn's algorithm
*/
mut v_degree := in_degree(graph) // return: map [string] int
print('V Degree $v_degree')
mut small_degree := min_degree(v_degree)
mut new_graph := remove_node_from_graph(small_degree, graph)
top_order << small_degree
count++
for (count < n_nodes) {
v_degree = in_degree(new_graph) // return: map [string] int
print('\nV Degree $v_degree')
small_degree = min_degree(v_degree)
new_graph = remove_node_from_graph(small_degree, new_graph)
top_order << small_degree
count++
}
// print("\n New Graph ${new_graph}")
return top_order
}
// Give a node, return a list with all nodes incidents or fathers of this node
fn all_fathers(node string, a_map map[string][]string) []string {
mut array_of_keys := a_map.keys() // get a key of this map
mut all_incident := []string{}
for i in array_of_keys {
// in : function
if node in a_map[i] {
all_incident << i // a queue of this search
}
}
return all_incident
}
// Input: a map with input degree values, return the key with smallest value
fn min_degree(a_map map[string]int) string {
mut array_of_keys := a_map.keys() // get a key of this map
mut key_min := array_of_keys.first()
mut val_min := a_map[key_min]
// print("\n MIN: ${val_min} \t key_min: ${key_min} \n the map inp_degree: ${a_map}")
for i in array_of_keys {
// there is a smaller
if val_min > a_map[i] {
val_min = a_map[i]
key_min = i
}
}
return key_min // the key with smallest value
}
// Given a graph ... return a list of integer with degree of each node
fn in_degree(a_map map[string][]string) map[string]int {
mut array_of_keys := a_map.keys() // get a key of this map
// print(array_of_keys)
mut degree := map[string]int{}
for i in array_of_keys {
degree[i] = all_fathers(i, a_map).len
}
// print("\n Degree ${in_degree}" )
return degree // a vector of the indegree graph
}
// REMOVE A NODE FROM A GRAPH AND RETURN ANOTHER GRAPH
fn remove_node_from_graph(node string, a_map map[string][]string) map[string][]string {
// mut new_graph := map [string] string {}
mut new_graph := a_map.clone() // copy the graph
new_graph.delete(node)
mut all_nodes := new_graph.keys() // get all nodes of this graph
// FOR THE FUTURE with filter
// for i in all_nodes {
// new_graph[i] = new_graph[i].filter(index(it) != node)
// }
// A HELP FROM V discussion GITHUB - thread
for key in all_nodes {
i := new_graph[key].index(node)
if i >= 0 {
new_graph[key].delete(i)
}
}
// print("\n NEW ${new_graph}" )
return new_graph
}
fn main() {
// A map illustration to use in a graph
// adjacency matrix
graph_01 := {
'A': ['C', 'B']
'B': ['D']
'C': ['D']
'D': []
}
graph_02 := {
'A': ['B', 'C', 'D']
'B': ['E']
'C': ['F']
'D': ['G']
'E': ['H']
'F': ['H']
'G': ['H']
'H': []
}
// from: https://en.wikipedia.org/wiki/Topological_sorting
graph_03 := {
'5': ['11']
'7': ['11', '8']
'3': ['8', '10']
'11': ['2', '9', '10']
'8': ['9']
'2': []
'9': []
'10': []
}
println('\nA Topological Sort of G1: ${topog_sort_greedy(graph_01)}')
println('\nA Topological Sort of G2: ${topog_sort_greedy(graph_02)}')
println('\nA Topological Sort of G3: ${topog_sort_greedy(graph_03)}')
// ['2', '9', '10', '11', '5', '8', '7', '3']
}

View File

@ -8,8 +8,8 @@ fn main() {
conn.close() or {}
}
println(' peer: $conn.peer_addr()')
println('local: $conn.addr()')
println(' peer: ${conn.peer_addr()?}')
println('local: ${conn.addr()?}')
// Simple http HEAD request for a file
conn.write_string('HEAD /index.html HTTP/1.0\r\n\r\n')?

View File

@ -9,7 +9,7 @@ fn main() {
println('------------------------------------------')
is_server := '-l' in os.args
port := cmdline.option(os.args, '-p', '40001').int()
mut buf := []byte{len: 100}
mut buf := []u8{len: 100}
if is_server {
println('UDP echo server, listening for udp packets on port: $port')
mut c := net.listen_udp(':$port')?

View File

@ -35,14 +35,14 @@ pub fn (s ImageSettings) to_grid_settings() sim.GridSettings {
pub struct PPMWriter {
mut:
file os.File
cache []byte
cache []u8
cache_size int
}
pub fn ppm_writer_for_fname(fname string, settings ImageSettings) ?&PPMWriter {
mut writer := &PPMWriter{
cache_size: settings.cache_size
cache: []byte{cap: settings.cache_size}
cache: []u8{cap: settings.cache_size}
}
writer.start_for_file(fname, settings)?
return writer

View File

@ -2,6 +2,6 @@ import rand
fn main() {
for _ in 0 .. 10 {
println('${rand.intn(255)}.${rand.intn(255)}.${rand.intn(255)}.${rand.intn(255)}')
println('${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}.${rand.intn(255)?}')
}
}

View File

@ -50,7 +50,7 @@ fn create_texture(w int, h int, buf &u8) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// commen if .dynamic is enabled
@ -68,7 +68,7 @@ fn destroy_texture(sg_img gfx.Image) {
}
// Use only if usage: .dynamic is enabled
fn update_text_texture(sg_img gfx.Image, w int, h int, buf &byte) {
fn update_text_texture(sg_img gfx.Image, w int, h int, buf &u8) {
sz := w * h * 4
mut tmp_sbc := gfx.ImageData{}
tmp_sbc.subimage[0][0] = gfx.Range{
@ -352,23 +352,23 @@ fn my_init(mut app App) {
x := (i & 0xFF) >> 5 // 8 cell
// upper left corner
if x == 0 && y == 0 {
tmp_txt[i] = byte(0xFF)
tmp_txt[i + 1] = byte(0)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i] = u8(0xFF)
tmp_txt[i + 1] = u8(0)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
}
// low right corner
else if x == 7 && y == 7 {
tmp_txt[i] = byte(0)
tmp_txt[i + 1] = byte(0xFF)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i] = u8(0)
tmp_txt[i + 1] = u8(0xFF)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
} else {
col := if ((x + y) & 1) == 1 { 0xFF } else { 0 }
tmp_txt[i] = byte(col) // red
tmp_txt[i + 1] = byte(col) // green
tmp_txt[i + 2] = byte(col) // blue
tmp_txt[i + 3] = byte(0xFF) // alpha
tmp_txt[i] = u8(col) // red
tmp_txt[i + 1] = u8(col) // green
tmp_txt[i + 2] = u8(col) // blue
tmp_txt[i + 3] = u8(0xFF) // alpha
}
i += 4
}

View File

@ -66,7 +66,7 @@ fn create_texture(w int, h int, buf &byte) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled
@ -524,23 +524,23 @@ fn my_init(mut app App) {
x := (i & 0xFF) >> 5 // 8 cell
// upper left corner
if x == 0 && y == 0 {
tmp_txt[i] = byte(0xFF)
tmp_txt[i + 1] = byte(0)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i] = u8(0xFF)
tmp_txt[i + 1] = u8(0)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
}
// low right corner
else if x == 7 && y == 7 {
tmp_txt[i + 0] = byte(0)
tmp_txt[i + 1] = byte(0xFF)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0)
tmp_txt[i + 1] = u8(0xFF)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
} else {
col := if ((x + y) & 1) == 1 { 0xFF } else { 128 }
tmp_txt[i + 0] = byte(col) // red
tmp_txt[i + 1] = byte(col) // green
tmp_txt[i + 2] = byte(col) // blue
tmp_txt[i + 3] = byte(0xFF) // alpha
tmp_txt[i + 0] = u8(col) // red
tmp_txt[i + 1] = u8(col) // green
tmp_txt[i + 2] = u8(col) // blue
tmp_txt[i + 3] = u8(0xFF) // alpha
}
i += 4
}

View File

@ -65,7 +65,7 @@ fn create_texture(w int, h int, buf &byte) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled
@ -342,23 +342,23 @@ fn my_init(mut app App) {
x := (i & 0xFF) >> 5 // 8 cell
// upper left corner
if x == 0 && y == 0 {
tmp_txt[i + 0] = byte(0xFF)
tmp_txt[i + 1] = byte(0)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0xFF)
tmp_txt[i + 1] = u8(0)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
}
// low right corner
else if x == 7 && y == 7 {
tmp_txt[i + 0] = byte(0)
tmp_txt[i + 1] = byte(0xFF)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0)
tmp_txt[i + 1] = u8(0xFF)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
} else {
col := if ((x + y) & 1) == 1 { 0xFF } else { 128 }
tmp_txt[i + 0] = byte(col) // red
tmp_txt[i + 1] = byte(col) // green
tmp_txt[i + 2] = byte(col) // blue
tmp_txt[i + 3] = byte(0xFF) // alpha
tmp_txt[i + 0] = u8(col) // red
tmp_txt[i + 1] = u8(col) // green
tmp_txt[i + 2] = u8(col) // blue
tmp_txt[i + 3] = u8(0xFF) // alpha
}
i += 4
}

View File

@ -67,7 +67,7 @@ fn create_texture(w int, h int, buf byteptr) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled
@ -530,23 +530,23 @@ fn my_init(mut app App) {
x := (i & 0xFF) >> 5 // 8 cell
// upper left corner
if x == 0 && y == 0 {
tmp_txt[i + 0] = byte(0xFF)
tmp_txt[i + 1] = byte(0)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0xFF)
tmp_txt[i + 1] = u8(0)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
}
// low right corner
else if x == 7 && y == 7 {
tmp_txt[i + 0] = byte(0)
tmp_txt[i + 1] = byte(0xFF)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0)
tmp_txt[i + 1] = u8(0xFF)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
} else {
col := if ((x + y) & 1) == 1 { 0xFF } else { 128 }
tmp_txt[i + 0] = byte(col) // red
tmp_txt[i + 1] = byte(col) // green
tmp_txt[i + 2] = byte(col) // blue
tmp_txt[i + 3] = byte(0xFF) // alpha
tmp_txt[i + 0] = u8(col) // red
tmp_txt[i + 1] = u8(col) // green
tmp_txt[i + 2] = u8(col) // blue
tmp_txt[i + 3] = u8(0xFF) // alpha
}
i += 4
}

View File

@ -80,7 +80,7 @@ fn create_texture(w int, h int, buf byteptr) gfx.Image{
//usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled
@ -406,23 +406,23 @@ fn my_init(mut app App) {
x := (i & 0xFF) >> 5 // 8 cell
// upper left corner
if x == 0 && y == 0 {
tmp_txt[i + 0] = byte(0xFF)
tmp_txt[i + 1] = byte(0)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0xFF)
tmp_txt[i + 1] = u8(0)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
}
// low right corner
else if x == 7 && y == 7 {
tmp_txt[i + 0] = byte(0)
tmp_txt[i + 1] = byte(0xFF)
tmp_txt[i + 2] = byte(0)
tmp_txt[i + 3] = byte(0xFF)
tmp_txt[i + 0] = u8(0)
tmp_txt[i + 1] = u8(0xFF)
tmp_txt[i + 2] = u8(0)
tmp_txt[i + 3] = u8(0xFF)
} else {
col := if ((x + y) & 1) == 1 { 0xFF } else { 128 }
tmp_txt[i + 0] = byte(col) // red
tmp_txt[i + 1] = byte(col) // green
tmp_txt[i + 2] = byte(col) // blue
tmp_txt[i + 3] = byte(0xFF) // alpha
tmp_txt[i + 0] = u8(col) // red
tmp_txt[i + 1] = u8(col) // green
tmp_txt[i + 2] = u8(col) // blue
tmp_txt[i + 3] = u8(0xFF) // alpha
}
i += 4
}

View File

@ -18,7 +18,7 @@ import stbi
/******************************************************************************
* Texture functions
******************************************************************************/
pub fn create_texture(w int, h int, buf &byte) gfx.Image {
pub fn create_texture(w int, h int, buf &u8) gfx.Image {
sz := w * h * 4
mut img_desc := gfx.ImageDesc{
width: w
@ -29,7 +29,7 @@ pub fn create_texture(w int, h int, buf &byte) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled

View File

@ -23,10 +23,10 @@ pub fn read_lines_from_file(file_path string) []string {
return rows
}
// read a file as []byte
pub fn read_bytes_from_file(file_path string) []byte {
// read a file as []u8
pub fn read_bytes_from_file(file_path string) []u8 {
mut path := ''
mut buffer := []byte{}
mut buffer := []u8{}
$if android {
path = 'models/' + file_path
buffer = os.read_apk_asset(path) or {

View File

@ -220,10 +220,10 @@ fn my_init(mut app App) {
// 1x1 pixel white, default texture
unsafe {
tmp_txt := malloc(4)
tmp_txt[0] = byte(0xFF)
tmp_txt[1] = byte(0xFF)
tmp_txt[2] = byte(0xFF)
tmp_txt[3] = byte(0xFF)
tmp_txt[0] = u8(0xFF)
tmp_txt[1] = u8(0xFF)
tmp_txt[2] = u8(0xFF)
tmp_txt[3] = u8(0xFF)
app.texture = obj.create_texture(1, 1, tmp_txt)
free(tmp_txt)
}

View File

@ -5,8 +5,8 @@ module particle
// * Color
pub struct Color {
mut:
r byte
g byte
b byte
a byte
r u8
g u8
b u8
a u8
}

View File

@ -46,10 +46,10 @@ pub fn (mut p Particle) update(dt f64) {
lt := p.life_time - (1000 * dt)
if lt > 0 {
p.life_time = lt
p.color.r = p.color.r - 1 // byte(remap(p.life_time,0.0,p.life_time_init,0,p.color.r))
p.color.g = p.color.g - 1 // byte(remap(p.life_time,0.0,p.life_time_init,0,p.color.g))
p.color.b = p.color.b - 1 // byte(remap(p.life_time,0.0,p.life_time_init,0,p.color.b))
p.color.a = byte(int(remap(p.life_time, 0.0, p.life_time_init, 0, 255))) - 10
p.color.r = p.color.r - 1 // u8(remap(p.life_time,0.0,p.life_time_init,0,p.color.r))
p.color.g = p.color.g - 1 // u8(remap(p.life_time,0.0,p.life_time_init,0,p.color.g))
p.color.b = p.color.b - 1 // u8(remap(p.life_time,0.0,p.life_time_init,0,p.color.b))
p.color.a = u8(int(remap(p.life_time, 0.0, p.life_time_init, 0, 255))) - 10
} else {
p.life_time = 0
}

View File

@ -22,7 +22,7 @@ fn my_audio_stream_callback(buffer &f32, num_frames int, num_channels int, mut a
for ch := 0; ch < num_channels; ch++ {
idx := frame * num_channels + ch
unsafe {
a := f32(byte(y) - 127) / 255.0
a := f32(u8(y) - 127) / 255.0
soundbuffer[idx] = a
acontext.frames[idx & 2047] = a
}
@ -61,8 +61,8 @@ fn graphics_frame(mut state AppState) {
}
[inline]
fn (mut state AppState) bsample(idx int) byte {
return byte(127 + state.frames[(state.gframe + idx) & 2047] * 128)
fn (mut state AppState) bsample(idx int) u8 {
return u8(127 + state.frames[(state.gframe + idx) & 2047] * 128)
}
fn (mut state AppState) draw() {

View File

@ -92,13 +92,13 @@ fn (mut p Player) free() {
// > MUST be placed before the Sound data chunk (but not necessarily
// > contiguous to the Sound data chunk).
struct RIFFHeader {
riff [4]byte
riff [4]u8
file_size u32
form_type [4]byte
form_type [4]u8
}
struct RIFFChunkHeader {
chunk_type [4]byte
chunk_type [4]u8
chunk_size u32
chunk_data voidptr
}
@ -113,21 +113,21 @@ struct RIFFFormat {
cbsize u16 // Size of the extension: 22
valid_bits_per_sample u16 // at most 8*M
channel_mask u32 // Speaker position mask
sub_format [16]byte // GUID
sub_format [16]u8 // GUID
}
fn read_wav_file_samples(fpath string) ?[]f32 {
mut res := []f32{}
// eprintln('> read_wav_file_samples: $fpath -------------------------------------------------')
mut bytes := os.read_bytes(fpath)?
mut pbytes := &byte(bytes.data)
mut pbytes := &u8(bytes.data)
mut offset := u32(0)
rh := unsafe { &RIFFHeader(pbytes) }
// eprintln('rh: $rh')
if rh.riff != [byte(`R`), `I`, `F`, `F`]! {
if rh.riff != [u8(`R`), `I`, `F`, `F`]! {
return error('WAV should start with `RIFF`')
}
if rh.form_type != [byte(`W`), `A`, `V`, `E`]! {
if rh.form_type != [u8(`W`), `A`, `V`, `E`]! {
return error('WAV should have `WAVE` form type')
}
if rh.file_size + 8 != bytes.len {
@ -145,15 +145,15 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
// eprintln('ch: $ch')
// eprintln('p: $pbytes | offset: $offset | bytes.len: $bytes.len')
// ////////
if ch.chunk_type == [byte(`L`), `I`, `S`, `T`]! {
if ch.chunk_type == [u8(`L`), `I`, `S`, `T`]! {
continue
}
//
if ch.chunk_type == [byte(`i`), `d`, `3`, ` `]! {
if ch.chunk_type == [u8(`i`), `d`, `3`, ` `]! {
continue
}
//
if ch.chunk_type == [byte(`f`), `m`, `t`, ` `]! {
if ch.chunk_type == [u8(`f`), `m`, `t`, ` `]! {
// eprintln('`fmt ` chunk')
rf = unsafe { &RIFFFormat(&ch.chunk_data) }
// eprintln('fmt riff format: $rf')
@ -169,20 +169,20 @@ fn read_wav_file_samples(fpath string) ?[]f32 {
continue
}
//
if ch.chunk_type == [byte(`d`), `a`, `t`, `a`]! {
if ch.chunk_type == [u8(`d`), `a`, `t`, `a`]! {
if rf == 0 {
return error('`data` chunk should be after `fmt ` chunk')
}
// eprintln('`fmt ` chunk: $rf\n`data` chunk: $ch')
mut doffset := 0
mut dp := unsafe { &byte(&ch.chunk_data) }
mut dp := unsafe { &u8(&ch.chunk_data) }
for doffset < ch.chunk_size {
for c := 0; c < rf.nchannels; c++ {
mut x := f32(0.0)
mut step := 0
ppos := unsafe { dp + doffset }
if rf.bits_per_sample == 8 {
d8 := unsafe { &byte(ppos) }
d8 := unsafe { &u8(ppos) }
x = (f32(*d8) - 128) / 128.0
step = 1
doffset++

View File

@ -0,0 +1,7 @@
Module {
name: 'submodule'
description: ''
version: ''
license: ''
dependencies: []
}

View File

@ -21,9 +21,9 @@ mut:
fn random_color() tui.Color {
return tui.Color{
r: rand.byte()
g: rand.byte()
b: rand.byte()
r: rand.u8()
g: rand.u8()
b: rand.u8()
}
}

View File

@ -126,7 +126,7 @@ fn create_texture(w int, h int, buf &u8) gfx.Image {
// usage: .dynamic
wrap_u: .clamp_to_edge
wrap_v: .clamp_to_edge
label: &byte(0)
label: &u8(0)
d3d11_texture: 0
}
// comment if .dynamic is enabled
@ -144,7 +144,7 @@ fn destroy_texture(sg_img gfx.Image) {
}
// Use only if: .dynamic is enabled
fn update_text_texture(sg_img gfx.Image, w int, h int, buf &byte) {
fn update_text_texture(sg_img gfx.Image, w int, h int, buf &u8) {
sz := w * h * 4
mut tmp_sbc := gfx.ImageData{}
tmp_sbc.subimage[0][0] = gfx.Range{
@ -215,9 +215,9 @@ fn (mut app App) read_bytes(path string) bool {
return true
}
// read a file as []byte
pub fn read_bytes_from_file(file_path string) []byte {
mut buffer := []byte{}
// read a file as []u8
pub fn read_bytes_from_file(file_path string) []u8 {
mut buffer := []u8{}
buffer = os.read_bytes(file_path) or {
eprintln('ERROR: Texure file: [$file_path] NOT FOUND.')
exit(0)
@ -428,7 +428,7 @@ fn frame(mut app App) {
// println("$w,$h")
// white multiplicator for now
mut c := [byte(255), 255, 255]!
mut c := [u8(255), 255, 255]!
sgl.begin_quads()
sgl.v2f_t2f_c3b(-w, -h, 0, 0, c[0], c[1], c[2])
sgl.v2f_t2f_c3b(w, -h, 1, 0, c[0], c[1], c[2])
@ -478,7 +478,7 @@ fn frame(mut app App) {
bx += (bw_old - bw) / 2 - (tr_x / 8) / app.scale
by += (bh_old - bh) / 2 - ((tr_y / 8) / app.scale) * ratio
c = [byte(255),255,0]! // yellow
c = [u8(255),255,0]! // yellow
sgl.begin_line_strip()
sgl.v2f_c3b(bx , by , c[0], c[1], c[2])
sgl.v2f_c3b(bx + bw, by , c[0], c[1], c[2])

View File

@ -13,7 +13,7 @@ fn main() {
x := rand.read(blocksize)?
for c in x {
if c >= `0` && c <= `~` {
sb.write_byte(c)
sb.write_u8(c)
}
}
if sb.len > size {

View File

@ -39,7 +39,7 @@ if !shift_counter! LSS 1 (
if "%~1" == "help" (
if not ["%~2"] == [""] set "subcmd=%~2"& shift& set /a shift_counter+=1
)
for %%z in (build clean cleanall help) do (
for %%z in (build clean cleanall check help) do (
if "%~1" == "%%z" set target=%1& shift& set /a shift_counter+=1& goto :verifyopt
)
)
@ -67,6 +67,12 @@ exit /b 2
:init
goto :!target!
:check
echo.
echo Check everything
v.exe test-all
exit /b 0
:cleanall
call :clean
if %ERRORLEVEL% NEQ 0 exit /b %ERRORLEVEL%
@ -119,7 +125,7 @@ REM By default, use tcc, since we have it prebuilt:
:tcc_strap
:tcc32_strap
echo ^> Attempting to build v_win.c with "!tcc_exe!"
"!tcc_exe!" -Bthirdparty/tcc -Ithirdparty/stdatomic/win -bt10 -g -w -o v.exe vc\v_win.c -ladvapi32
"!tcc_exe!" -Bthirdparty/tcc -bt10 -g -w -o v.exe vc\v_win.c -ladvapi32
if %ERRORLEVEL% NEQ 0 goto :compile_error
echo ^> Compiling .\v.exe with itself
v.exe -keepc -g -showcc -cc "!tcc_exe!" -cflags -Bthirdparty/tcc -o v2.exe cmd/v
@ -137,7 +143,7 @@ if %ERRORLEVEL% NEQ 0 (
)
echo ^> Attempting to build v_win.c with Clang
clang -std=c99 -Ithirdparty/stdatomic/win -municode -g -w -o v.exe .\vc\v_win.c -ladvapi32
clang -std=c99 -municode -g -w -o v.exe .\vc\v_win.c -ladvapi32
if %ERRORLEVEL% NEQ 0 (
echo In most cases, compile errors happen because the version of Clang installed is too old
clang --version
@ -160,7 +166,7 @@ if %ERRORLEVEL% NEQ 0 (
)
echo ^> Attempting to build v_win.c with GCC
gcc -std=c99 -municode -Ithirdparty/stdatomic/win -g -w -o v.exe .\vc\v_win.c -ladvapi32
gcc -std=c99 -municode -g -w -o v.exe .\vc\v_win.c -ladvapi32
if %ERRORLEVEL% NEQ 0 (
echo In most cases, compile errors happen because the version of GCC installed is too old
gcc --version
@ -202,7 +208,7 @@ if exist "%InstallDir%\Common7\Tools\vsdevcmd.bat" (
set ObjFile=.v.c.obj
echo ^> Attempting to build v_win.c with MSVC
cl.exe /volatile:ms /I thirdparty\stdatomic\win /Fo%ObjFile% /O2 /MD /D_VBOOTSTRAP vc\v_win.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /nologo /out:v.exe /incremental:no
cl.exe /volatile:ms /Fo%ObjFile% /O2 /MD /D_VBOOTSTRAP vc\v_win.c user32.lib kernel32.lib advapi32.lib shell32.lib /link /nologo /out:v.exe /incremental:no
if %ERRORLEVEL% NEQ 0 (
echo In some cases, compile errors happen because of the MSVC compiler version
cl.exe
@ -262,7 +268,8 @@ echo Target:
echo build[default] Compiles V using the given C compiler
echo clean Clean build artifacts and debugging symbols
echo cleanall Cleanup entire ALL build artifacts and vc repository
echo help Display usage help for the given target
echo check Check that tests pass, and the repository is in a good shape for Pull Requests
echo help Display help for the given target
echo.
echo Examples:
echo make.bat -msvc

View File

@ -0,0 +1,4 @@
The libbacktrace source is distributed here as an amalgamation (https://sqlite.org/amalgamation.html).
This means that, rather than mirroring the entire libbacktrace repo here, most of the source code is
packaged into one C file while other platform-specific code are into their respective C files which
is much easier to handle.

View File

@ -0,0 +1,111 @@
/* Copyright (C) 2012-2021 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#define HAVE_ATOMIC_FUNCTIONS 1
#define HAVE_CLOCK_GETTIME 1
#define HAVE_DECL_GETPAGESIZE 0
#define HAVE_DECL_STRNLEN 1
#define HAVE_DL_ITERATE_PHDR 1
#define HAVE_GETIPINFO 1
#define HAVE_LSTAT 1
#define HAVE_READLINK 1
#define HAVE_SYNC_FUNCTIONS 1
#define HAVE_DLFCN_H 1
#define HAVE_INTTYPES_H 1
#define HAVE_LINK_H 1
#define HAVE_MEMORY_H 1
#define HAVE_STDINT_H 1
#define HAVE_STDLIB_H 1
#define HAVE_STRINGS_H 1
#define HAVE_STRING_H 1
#define HAVE_UNISTD_H 1
#define STDC_HEADERS 1
#include <stdint.h>
#if UINTPTR_MAX == 0xFFFFFFFF
#define BACKTRACE_ELF_SIZE 32
#define BACKTRACE_XCOFF_SIZE 32
#elif UINTPTR_MAX == 0xFFFFFFFFFFFFFFFFu
#define BACKTRACE_ELF_SIZE 64
#define BACKTRACE_XCOFF_SIZE 64
#endif
#ifdef __TINYC__
#undef HAVE_ATOMIC_FUNCTIONS
#undef HAVE_SYNC_FUNCTIONS
#endif
#ifndef _WIN32
#define HAVE_FCNTL 1
#endif
#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#define HAVE_KERN_PROC 1
#define HAVE_KERN_PROC_ARGS 1
#endif
#ifdef __APPLE__
#define HAVE_MACH_O_DYLD_H 1
#endif
#ifndef _ALL_SOURCE
#define _ALL_SOURCE 1
#endif
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#undef HAVE_DL_ITERATE_PHDR
#endif
#ifndef _POSIX_PTHREAD_SEMANTICS
#define _POSIX_PTHREAD_SEMANTICS 1
#endif
#ifndef _TANDEM_SOURCE
#define _TANDEM_SOURCE 1
#endif
#ifndef __EXTENSIONS__
#define __EXTENSIONS__ 1
#endif
#ifndef _DARWIN_USE_64_BIT_INODE
#define _DARWIN_USE_64_BIT_INODE 1
#endif
#define BACKTRACE_SUPPORTED 1
#define BACKTRACE_USES_MALLOC 1
#define BACKTRACE_SUPPORTS_THREADS 1
#define BACKTRACE_SUPPORTS_DATA 0
#if __TINYC__
#undef BACKTRACE_SUPPORTED
#endif
#include "base.c"
#if defined(__linux__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
#include "linux.c"
#elif defined(__APPLE__)
#include "darwin.c"
#elif defined(_WIN32)
#include "windows.c"
#endif

View File

@ -0,0 +1,189 @@
/* backtrace.h -- Public header file for stack backtrace library.
Copyright (C) 2012-2021 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Google.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
(1) Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
(2) Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
(3) The name of the author may not be used to
endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE. */
#ifndef BACKTRACE_H
#define BACKTRACE_H
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The backtrace state. This struct is intentionally not defined in
the public interface. */
struct backtrace_state;
/* The type of the error callback argument to backtrace functions.
This function, if not NULL, will be called for certain error cases.
The DATA argument is passed to the function that calls this one.
The MSG argument is an error message. The ERRNUM argument, if
greater than 0, holds an errno value. The MSG buffer may become
invalid after this function returns.
As a special case, the ERRNUM argument will be passed as -1 if no
debug info can be found for the executable, or if the debug info
exists but has an unsupported version, but the function requires
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
this case will be something along the lines of "no debug info".
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
but the function requires a symbol table (e.g., backtrace_syminfo).
This may be used as a signal that some other approach should be
tried. */
typedef void (*backtrace_error_callback) (void *data, const char *msg,
int errnum);
/* Create state information for the backtrace routines. This must be
called before any of the other routines, and its return value must
be passed to all of the other routines. FILENAME is the path name
of the executable file; if it is NULL the library will try
system-specific path names. If not NULL, FILENAME must point to a
permanent buffer. If THREADED is non-zero the state may be
accessed by multiple threads simultaneously, and the library will
use appropriate atomic operations. If THREADED is zero the state
may only be accessed by one thread at a time. This returns a state
pointer on success, NULL on error. If an error occurs, this will
call the ERROR_CALLBACK routine.
Calling this function allocates resources that cannot be freed.
There is no backtrace_free_state function. The state is used to
cache information that is expensive to recompute. Programs are
expected to call this function at most once and to save the return
value for all later calls to backtrace functions. */
extern struct backtrace_state *backtrace_create_state (
const char *filename, int threaded,
backtrace_error_callback error_callback, void *data);
/* The type of the callback argument to the backtrace_full function.
DATA is the argument passed to backtrace_full. PC is the program
counter. FILENAME is the name of the file containing PC, or NULL
if not available. LINENO is the line number in FILENAME containing
PC, or 0 if not available. FUNCTION is the name of the function
containing PC, or NULL if not available. This should return 0 to
continuing tracing. The FILENAME and FUNCTION buffers may become
invalid after this function returns. */
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
const char *filename, int lineno,
const char *function);
/* Get a full stack backtrace. SKIP is the number of frames to skip;
passing 0 will start the trace with the function calling
backtrace_full. DATA is passed to the callback routine. If any
call to CALLBACK returns a non-zero value, the stack backtrace
stops, and backtrace returns that value; this may be used to limit
the number of stack frames desired. If all calls to CALLBACK
return 0, backtrace returns 0. The backtrace_full function will
make at least one call to either CALLBACK or ERROR_CALLBACK. This
function requires debug info for the executable. */
extern int backtrace_full (struct backtrace_state *state, int skip,
backtrace_full_callback callback,
backtrace_error_callback error_callback,
void *data);
/* The type of the callback argument to the backtrace_simple function.
DATA is the argument passed to simple_backtrace. PC is the program
counter. This should return 0 to continue tracing. */
typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
/* Get a simple backtrace. SKIP is the number of frames to skip, as
in backtrace. DATA is passed to the callback routine. If any call
to CALLBACK returns a non-zero value, the stack backtrace stops,
and backtrace_simple returns that value. Otherwise
backtrace_simple returns 0. The backtrace_simple function will
make at least one call to either CALLBACK or ERROR_CALLBACK. This
function does not require any debug info for the executable. */
extern int backtrace_simple (struct backtrace_state *state, int skip,
backtrace_simple_callback callback,
backtrace_error_callback error_callback,
void *data);
/* Print the current backtrace in a user readable format to a FILE.
SKIP is the number of frames to skip, as in backtrace_full. Any
error messages are printed to stderr. This function requires debug
info for the executable. */
extern void backtrace_print (struct backtrace_state *state, int skip, FILE *);
/* Given PC, a program counter in the current program, call the
callback function with filename, line number, and function name
information. This will normally call the callback function exactly
once. However, if the PC happens to describe an inlined call, and
the debugging information contains the necessary information, then
this may call the callback function multiple times. This will make
at least one call to either CALLBACK or ERROR_CALLBACK. This
returns the first non-zero value returned by CALLBACK, or 0. */
extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
backtrace_full_callback callback,
backtrace_error_callback error_callback,
void *data);
/* The type of the callback argument to backtrace_syminfo. DATA and
PC are the arguments passed to backtrace_syminfo. SYMNAME is the
name of the symbol for the corresponding code. SYMVAL is the
value and SYMSIZE is the size of the symbol. SYMNAME will be NULL
if no error occurred but the symbol could not be found. */
typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
const char *symname,
uintptr_t symval,
uintptr_t symsize);
/* Given ADDR, an address or program counter in the current program,
call the callback information with the symbol name and value
describing the function or variable in which ADDR may be found.
This will call either CALLBACK or ERROR_CALLBACK exactly once.
This returns 1 on success, 0 on failure. This function requires
the symbol table but does not require the debug info. Note that if
the symbol table is present but ADDR could not be found in the
table, CALLBACK will be called with a NULL SYMNAME argument.
Returns 1 on success, 0 on error. */
extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t addr,
backtrace_syminfo_callback callback,
backtrace_error_callback error_callback,
void *data);
#ifdef __cplusplus
} /* End extern "C". */
#endif
#endif

4303
thirdparty/libbacktrace/base.c vendored 100644

File diff suppressed because it is too large Load Diff

1298
thirdparty/libbacktrace/darwin.c vendored 100644

File diff suppressed because it is too large Load Diff

3865
thirdparty/libbacktrace/linux.c vendored 100644

File diff suppressed because it is too large Load Diff

818
thirdparty/libbacktrace/windows.c vendored 100644
View File

@ -0,0 +1,818 @@
// pecoff.c:
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
typedef struct {
uint16_t machine;
uint16_t number_of_sections;
uint32_t time_date_stamp;
uint32_t pointer_to_symbol_table;
uint32_t number_of_symbols;
uint16_t size_of_optional_header;
uint16_t characteristics;
} b_coff_file_header;
typedef struct {
uint16_t magic;
uint8_t major_linker_version;
uint8_t minor_linker_version;
uint32_t size_of_code;
uint32_t size_of_initialized_data;
uint32_t size_of_uninitialized_data;
uint32_t address_of_entry_point;
uint32_t base_of_code;
union {
struct {
uint32_t base_of_data;
uint32_t image_base;
} pe;
struct {
uint64_t image_base;
} pep;
} u;
} b_coff_optional_header;
#define PE_MAGIC 0x10b
#define PEP_MAGIC 0x20b
typedef struct {
char name[8];
uint32_t virtual_size;
uint32_t virtual_address;
uint32_t size_of_raw_data;
uint32_t pointer_to_raw_data;
uint32_t pointer_to_relocations;
uint32_t pointer_to_line_numbers;
uint16_t number_of_relocations;
uint16_t number_of_line_numbers;
uint32_t characteristics;
} b_coff_section_header;
typedef union {
char short_name[8];
struct {
unsigned char zeroes[4];
unsigned char off[4];
} long_name;
} b_coff_name;
typedef struct {
b_coff_name name;
unsigned char value[4];
unsigned char section_number[2];
unsigned char type[2];
unsigned char storage_class;
unsigned char number_of_aux_symbols;
} b_coff_external_symbol;
#define N_TBSHFT 4
#define IMAGE_SYM_DTYPE_FUNCTION 2
#define SYM_SZ 18
typedef struct {
const char *name;
uint32_t value;
int16_t sec;
uint16_t type;
uint16_t sc;
} b_coff_internal_symbol;
static const char *const debug_section_names[DEBUG_MAX] = {
".debug_info", ".debug_line", ".debug_abbrev",
".debug_ranges", ".debug_str", ".debug_addr",
".debug_str_offsets", ".debug_line_str", ".debug_rnglists"};
struct debug_section_info {
off_t offset;
size_t size;
};
struct coff_symbol {
const char *name;
uintptr_t address;
};
struct coff_syminfo_data {
struct coff_syminfo_data *next;
struct coff_symbol *symbols;
size_t count;
};
static int coff_nodebug(struct backtrace_state *state ATTRIBUTE_UNUSED,
uintptr_t pc ATTRIBUTE_UNUSED,
backtrace_full_callback callback ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback, void *data) {
error_callback(data, "no debug info in PE/COFF executable", -1);
return 0;
}
static void coff_nosyms(struct backtrace_state *state ATTRIBUTE_UNUSED,
uintptr_t addr ATTRIBUTE_UNUSED,
backtrace_syminfo_callback callback ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback, void *data) {
error_callback(data, "no symbol table in PE/COFF executable", -1);
}
static uint32_t coff_read4(const unsigned char *p) {
uint32_t res;
memcpy(&res, p, 4);
return res;
}
static uint16_t coff_read2(const unsigned char *p) {
uint16_t res;
memcpy(&res, p, sizeof(res));
return res;
}
static size_t coff_short_name_len(const char *name) {
int i;
for (i = 0; i < 8; i++)
if (name[i] == 0) return i;
return 8;
}
static int coff_short_name_eq(const char *name, const char *cname) {
int i;
for (i = 0; i < 8; i++) {
if (name[i] != cname[i]) return 0;
if (name[i] == 0) return 1;
}
return name[8] == 0;
}
static int coff_long_name_eq(const char *name, unsigned int off,
struct backtrace_view *str_view) {
if (off >= str_view->len) return 0;
return strcmp(name, (const char *)str_view->data + off) == 0;
}
static int coff_symbol_compare(const void *v1, const void *v2) {
const struct coff_symbol *e1 = (const struct coff_symbol *)v1;
const struct coff_symbol *e2 = (const struct coff_symbol *)v2;
if (e1->address < e2->address)
return -1;
else if (e1->address > e2->address)
return 1;
else
return 0;
}
static int coff_expand_symbol(b_coff_internal_symbol *isym,
const b_coff_external_symbol *sym,
uint16_t sects_num, const unsigned char *strtab,
size_t strtab_size) {
isym->type = coff_read2(sym->type);
isym->sec = coff_read2(sym->section_number);
isym->sc = sym->storage_class;
if (isym->sec > 0 && (uint16_t)isym->sec > sects_num) return -1;
if (sym->name.short_name[0] != 0)
isym->name = sym->name.short_name;
else {
uint32_t off = coff_read4(sym->name.long_name.off);
if (off >= strtab_size) return -1;
isym->name = (const char *)strtab + off;
}
return 0;
}
static int coff_is_function_symbol(const b_coff_internal_symbol *isym) {
return (isym->type >> N_TBSHFT) == IMAGE_SYM_DTYPE_FUNCTION && isym->sec > 0;
}
static int coff_initialize_syminfo(
struct backtrace_state *state, uintptr_t base_address, int is_64,
const b_coff_section_header *sects, size_t sects_num,
const b_coff_external_symbol *syms, size_t syms_size,
const unsigned char *strtab, size_t strtab_size,
backtrace_error_callback error_callback, void *data,
struct coff_syminfo_data *sdata) {
size_t syms_count;
char *coff_symstr;
size_t coff_symstr_len;
size_t coff_symbol_count;
size_t coff_symbol_size;
struct coff_symbol *coff_symbols;
struct coff_symbol *coff_sym;
char *coff_str;
size_t i;
syms_count = syms_size / SYM_SZ;
coff_symbol_count = 0;
coff_symstr_len = 0;
for (i = 0; i < syms_count; ++i) {
const b_coff_external_symbol *asym = &syms[i];
b_coff_internal_symbol isym;
if (coff_expand_symbol(&isym, asym, sects_num, strtab, strtab_size) < 0) {
error_callback(data, "invalid section or offset in coff symbol", 0);
return 0;
}
if (coff_is_function_symbol(&isym)) {
++coff_symbol_count;
if (asym->name.short_name[0] != 0)
coff_symstr_len += coff_short_name_len(asym->name.short_name) + 1;
}
i += asym->number_of_aux_symbols;
}
coff_symbol_size = (coff_symbol_count + 1) * sizeof(struct coff_symbol);
coff_symbols = ((struct coff_symbol *)backtrace_alloc(state, coff_symbol_size,
error_callback, data));
if (coff_symbols == NULL) return 0;
if (coff_symstr_len > 0) {
coff_symstr =
((char *)backtrace_alloc(state, coff_symstr_len, error_callback, data));
if (coff_symstr == NULL) {
backtrace_free(state, coff_symbols, coff_symbol_size, error_callback,
data);
return 0;
}
} else
coff_symstr = NULL;
coff_sym = coff_symbols;
coff_str = coff_symstr;
for (i = 0; i < syms_count; ++i) {
const b_coff_external_symbol *asym = &syms[i];
b_coff_internal_symbol isym;
if (coff_expand_symbol(&isym, asym, sects_num, strtab, strtab_size)) {
abort();
}
if (coff_is_function_symbol(&isym)) {
const char *name;
int16_t secnum;
if (asym->name.short_name[0] != 0) {
size_t len = coff_short_name_len(isym.name);
name = coff_str;
memcpy(coff_str, isym.name, len);
coff_str[len] = 0;
coff_str += len + 1;
} else
name = isym.name;
if (!is_64) {
if (name[0] == '_') name++;
}
secnum = coff_read2(asym->section_number);
coff_sym->name = name;
coff_sym->address = (coff_read4(asym->value) +
sects[secnum - 1].virtual_address + base_address);
coff_sym++;
}
i += asym->number_of_aux_symbols;
}
coff_sym->name = NULL;
coff_sym->address = -1;
backtrace_qsort(coff_symbols, coff_symbol_count, sizeof(struct coff_symbol),
coff_symbol_compare);
sdata->next = NULL;
sdata->symbols = coff_symbols;
sdata->count = coff_symbol_count;
return 1;
}
static void coff_add_syminfo_data(struct backtrace_state *state,
struct coff_syminfo_data *sdata) {
if (!state->threaded) {
struct coff_syminfo_data **pp;
for (pp = (struct coff_syminfo_data **)(void *)&state->syminfo_data;
*pp != NULL; pp = &(*pp)->next)
;
*pp = sdata;
} else {
while (1) {
struct coff_syminfo_data **pp;
pp = (struct coff_syminfo_data **)(void *)&state->syminfo_data;
while (1) {
struct coff_syminfo_data *p;
p = backtrace_atomic_load_pointer(pp);
if (p == NULL) break;
pp = &p->next;
}
if (__sync_bool_compare_and_swap(pp, NULL, sdata)) break;
}
}
}
static int coff_symbol_search(const void *vkey, const void *ventry) {
const uintptr_t *key = (const uintptr_t *)vkey;
const struct coff_symbol *entry = (const struct coff_symbol *)ventry;
uintptr_t addr;
addr = *key;
if (addr < entry->address)
return -1;
else if (addr >= entry[1].address)
return 1;
else
return 0;
}
static void coff_syminfo(
struct backtrace_state *state, uintptr_t addr,
backtrace_syminfo_callback callback,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED, void *data) {
struct coff_syminfo_data *sdata;
struct coff_symbol *sym = NULL;
if (!state->threaded) {
for (sdata = (struct coff_syminfo_data *)state->syminfo_data; sdata != NULL;
sdata = sdata->next) {
sym = ((struct coff_symbol *)bsearch(&addr, sdata->symbols, sdata->count,
sizeof(struct coff_symbol),
coff_symbol_search));
if (sym != NULL) break;
}
} else {
struct coff_syminfo_data **pp;
pp = (struct coff_syminfo_data **)(void *)&state->syminfo_data;
while (1) {
sdata = backtrace_atomic_load_pointer(pp);
if (sdata == NULL) break;
sym = ((struct coff_symbol *)bsearch(&addr, sdata->symbols, sdata->count,
sizeof(struct coff_symbol),
coff_symbol_search));
if (sym != NULL) break;
pp = &sdata->next;
}
}
if (sym == NULL)
callback(data, addr, NULL, 0, 0);
else
callback(data, addr, sym->name, sym->address, 0);
}
static int coff_add(struct backtrace_state *state, int descriptor,
backtrace_error_callback error_callback, void *data,
fileline *fileline_fn, int *found_sym, int *found_dwarf) {
struct backtrace_view fhdr_view;
off_t fhdr_off;
int magic_ok;
b_coff_file_header fhdr;
off_t opt_sects_off;
size_t opt_sects_size;
unsigned int sects_num;
struct backtrace_view sects_view;
int sects_view_valid;
const b_coff_optional_header *opt_hdr;
const b_coff_section_header *sects;
struct backtrace_view str_view;
int str_view_valid;
size_t str_size;
off_t str_off;
struct backtrace_view syms_view;
off_t syms_off;
size_t syms_size;
int syms_view_valid;
unsigned int syms_num;
unsigned int i;
struct debug_section_info sections[DEBUG_MAX];
off_t min_offset;
off_t max_offset;
struct backtrace_view debug_view;
int debug_view_valid;
int is_64;
uintptr_t image_base;
struct dwarf_sections dwarf_sections;
*found_sym = 0;
*found_dwarf = 0;
sects_view_valid = 0;
syms_view_valid = 0;
str_view_valid = 0;
debug_view_valid = 0;
if (!backtrace_get_view(state, descriptor, 0, 0x40, error_callback, data,
&fhdr_view))
goto fail;
{
const unsigned char *vptr = fhdr_view.data;
if (vptr[0] == 'M' && vptr[1] == 'Z')
fhdr_off = coff_read4(vptr + 0x3c);
else
fhdr_off = 0;
}
backtrace_release_view(state, &fhdr_view, error_callback, data);
if (!backtrace_get_view(state, descriptor, fhdr_off,
sizeof(b_coff_file_header) + 4, error_callback, data,
&fhdr_view))
goto fail;
if (fhdr_off != 0) {
const char *magic = (const char *)fhdr_view.data;
magic_ok = memcmp(magic, "PE\0", 4) == 0;
fhdr_off += 4;
memcpy(&fhdr, fhdr_view.data + 4, sizeof fhdr);
} else {
memcpy(&fhdr, fhdr_view.data, sizeof fhdr);
magic_ok = 0;
}
backtrace_release_view(state, &fhdr_view, error_callback, data);
if (!magic_ok) {
error_callback(data, "executable file is not COFF", 0);
goto fail;
}
sects_num = fhdr.number_of_sections;
syms_num = fhdr.number_of_symbols;
opt_sects_off = fhdr_off + sizeof(fhdr);
opt_sects_size = (fhdr.size_of_optional_header +
sects_num * sizeof(b_coff_section_header));
if (!backtrace_get_view(state, descriptor, opt_sects_off, opt_sects_size,
error_callback, data, &sects_view))
goto fail;
sects_view_valid = 1;
opt_hdr = (const b_coff_optional_header *)sects_view.data;
sects = (const b_coff_section_header *)(sects_view.data +
fhdr.size_of_optional_header);
is_64 = 0;
if (fhdr.size_of_optional_header > sizeof(*opt_hdr)) {
if (opt_hdr->magic == PE_MAGIC)
image_base = opt_hdr->u.pe.image_base;
else if (opt_hdr->magic == PEP_MAGIC) {
image_base = opt_hdr->u.pep.image_base;
is_64 = 1;
} else {
error_callback(data, "bad magic in PE optional header", 0);
goto fail;
}
} else
image_base = 0;
if (fhdr.pointer_to_symbol_table == 0) {
str_off = 0;
str_size = 0;
syms_num = 0;
syms_size = 0;
} else {
syms_off = fhdr.pointer_to_symbol_table;
syms_size = syms_num * SYM_SZ;
if (!backtrace_get_view(state, descriptor, syms_off, syms_size + 4,
error_callback, data, &syms_view))
goto fail;
syms_view_valid = 1;
str_size = coff_read4(syms_view.data + syms_size);
str_off = syms_off + syms_size;
if (str_size > 4) {
if (!backtrace_get_view(state, descriptor, str_off, str_size,
error_callback, data, &str_view))
goto fail;
str_view_valid = 1;
}
}
memset(sections, 0, sizeof sections);
for (i = 0; i < sects_num; ++i) {
const b_coff_section_header *s = sects + i;
unsigned int str_off;
int j;
if (s->name[0] == '/') {
str_off = atoi(s->name + 1);
} else
str_off = 0;
for (j = 0; j < (int)DEBUG_MAX; ++j) {
const char *dbg_name = debug_section_names[j];
int match;
if (str_off != 0)
match = coff_long_name_eq(dbg_name, str_off, &str_view);
else
match = coff_short_name_eq(dbg_name, s->name);
if (match) {
sections[j].offset = s->pointer_to_raw_data;
sections[j].size = s->virtual_size <= s->size_of_raw_data
? s->virtual_size
: s->size_of_raw_data;
break;
}
}
}
if (syms_num != 0) {
struct coff_syminfo_data *sdata;
sdata = ((struct coff_syminfo_data *)backtrace_alloc(state, sizeof *sdata,
error_callback, data));
if (sdata == NULL) goto fail;
if (!coff_initialize_syminfo(state, image_base, is_64, sects, sects_num,
syms_view.data, syms_size, str_view.data,
str_size, error_callback, data, sdata)) {
backtrace_free(state, sdata, sizeof *sdata, error_callback, data);
goto fail;
}
*found_sym = 1;
coff_add_syminfo_data(state, sdata);
}
backtrace_release_view(state, &sects_view, error_callback, data);
sects_view_valid = 0;
if (syms_view_valid) {
backtrace_release_view(state, &syms_view, error_callback, data);
syms_view_valid = 0;
}
min_offset = 0;
max_offset = 0;
for (i = 0; i < (int)DEBUG_MAX; ++i) {
off_t end;
if (sections[i].size == 0) continue;
if (min_offset == 0 || sections[i].offset < min_offset)
min_offset = sections[i].offset;
end = sections[i].offset + sections[i].size;
if (end > max_offset) max_offset = end;
}
if (min_offset == 0 || max_offset == 0) {
if (!backtrace_close(descriptor, error_callback, data)) goto fail;
*fileline_fn = coff_nodebug;
return 1;
}
if (!backtrace_get_view(state, descriptor, min_offset,
max_offset - min_offset, error_callback, data,
&debug_view))
goto fail;
debug_view_valid = 1;
if (!backtrace_close(descriptor, error_callback, data)) goto fail;
descriptor = -1;
for (i = 0; i < (int)DEBUG_MAX; ++i) {
size_t size = sections[i].size;
dwarf_sections.size[i] = size;
if (size == 0)
dwarf_sections.data[i] = NULL;
else
dwarf_sections.data[i] = ((const unsigned char *)debug_view.data +
(sections[i].offset - min_offset));
}
if (!backtrace_dwarf_add(state, 0, &dwarf_sections, 0, NULL, error_callback,
data, fileline_fn, NULL))
goto fail;
*found_dwarf = 1;
return 1;
fail:
if (sects_view_valid)
backtrace_release_view(state, &sects_view, error_callback, data);
if (str_view_valid)
backtrace_release_view(state, &str_view, error_callback, data);
if (syms_view_valid)
backtrace_release_view(state, &syms_view, error_callback, data);
if (debug_view_valid)
backtrace_release_view(state, &debug_view, error_callback, data);
if (descriptor != -1) backtrace_close(descriptor, error_callback, data);
return 0;
}
int backtrace_initialize(struct backtrace_state *state,
const char *filename ATTRIBUTE_UNUSED, int descriptor,
backtrace_error_callback error_callback, void *data,
fileline *fileline_fn) {
int ret;
int found_sym;
int found_dwarf;
fileline coff_fileline_fn;
ret = coff_add(state, descriptor, error_callback, data, &coff_fileline_fn,
&found_sym, &found_dwarf);
if (!ret) return 0;
if (!state->threaded) {
if (found_sym)
state->syminfo_fn = coff_syminfo;
else if (state->syminfo_fn == NULL)
state->syminfo_fn = coff_nosyms;
} else {
if (found_sym)
backtrace_atomic_store_pointer(&state->syminfo_fn, coff_syminfo);
else
(void)__sync_bool_compare_and_swap(&state->syminfo_fn, NULL, coff_nosyms);
}
if (!state->threaded) {
if (state->fileline_fn == NULL || state->fileline_fn == coff_nodebug)
*fileline_fn = coff_fileline_fn;
} else {
fileline current_fn;
current_fn = backtrace_atomic_load_pointer(&state->fileline_fn);
if (current_fn == NULL || current_fn == coff_nodebug)
*fileline_fn = coff_fileline_fn;
}
return 1;
}
// read.c:
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int backtrace_get_view(struct backtrace_state *state, int descriptor,
off_t offset, uint64_t size,
backtrace_error_callback error_callback, void *data,
struct backtrace_view *view) {
uint64_t got;
ssize_t r;
if ((uint64_t)(size_t)size != size) {
error_callback(data, "file size too large", 0);
return 0;
}
if (lseek(descriptor, offset, SEEK_SET) < 0) {
error_callback(data, "lseek", errno);
return 0;
}
view->base = backtrace_alloc(state, size, error_callback, data);
if (view->base == NULL) return 0;
view->data = view->base;
view->len = size;
got = 0;
while (got < size) {
r = read(descriptor, view->base, size - got);
if (r < 0) {
error_callback(data, "read", errno);
free(view->base);
return 0;
}
if (r == 0) break;
got += (uint64_t)r;
}
if (got < size) {
error_callback(data, "file too short", 0);
free(view->base);
return 0;
}
return 1;
}
void backtrace_release_view(struct backtrace_state *state,
struct backtrace_view *view,
backtrace_error_callback error_callback,
void *data) {
backtrace_free(state, view->base, view->len, error_callback, data);
view->data = NULL;
view->base = NULL;
}
// alloc.c:
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
void *backtrace_alloc(struct backtrace_state *state ATTRIBUTE_UNUSED,
size_t size, backtrace_error_callback error_callback,
void *data) {
void *ret;
ret = malloc(size);
if (ret == NULL) {
if (error_callback) error_callback(data, "malloc", errno);
}
return ret;
}
void backtrace_free(struct backtrace_state *state ATTRIBUTE_UNUSED, void *p,
size_t size ATTRIBUTE_UNUSED,
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
void *data ATTRIBUTE_UNUSED) {
free(p);
}
void *backtrace_vector_grow(struct backtrace_state *state ATTRIBUTE_UNUSED,
size_t size,
backtrace_error_callback error_callback, void *data,
struct backtrace_vector *vec) {
void *ret;
if (size > vec->alc) {
size_t alc;
void *base;
if (vec->size == 0)
alc = 32 * size;
else if (vec->size >= 4096)
alc = vec->size + 4096;
else
alc = 2 * vec->size;
if (alc < vec->size + size) alc = vec->size + size;
base = realloc(vec->base, alc);
if (base == NULL) {
error_callback(data, "realloc", errno);
return NULL;
}
vec->base = base;
vec->alc = alc - vec->size;
}
ret = (char *)vec->base + vec->size;
vec->size += size;
vec->alc -= size;
return ret;
}
void *backtrace_vector_finish(struct backtrace_state *state,
struct backtrace_vector *vec,
backtrace_error_callback error_callback,
void *data) {
void *ret;
if (!backtrace_vector_release(state, vec, error_callback, data)) return NULL;
ret = vec->base;
vec->base = NULL;
vec->size = 0;
vec->alc = 0;
return ret;
}
int backtrace_vector_release(struct backtrace_state *state ATTRIBUTE_UNUSED,
struct backtrace_vector *vec,
backtrace_error_callback error_callback,
void *data) {
vec->alc = 0;
if (vec->size == 0) {
free(vec->base);
vec->base = NULL;
return 1;
}
vec->base = realloc(vec->base, vec->size);
if (vec->base == NULL) {
error_callback(data, "realloc", errno);
return 0;
}
return 1;
}

4235
thirdparty/libgc/gc.c vendored

File diff suppressed because it is too large Load Diff

1081
thirdparty/libgc/gc.h vendored

File diff suppressed because it is too large Load Diff

2
thirdparty/libgc/include/gc.h vendored 100644
View File

@ -0,0 +1,2 @@
/* This file is installed for backward compatibility. */
#include <gc/gc.h>

View File

@ -0,0 +1,377 @@
/*
* Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
* Permission is hereby granted to use or copy this program
* for any purpose, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
/*
* Cords are immutable character strings. A number of operations
* on long cords are much more efficient than their strings.h counterpart.
* In particular, concatenation takes constant time independent of the length
* of the arguments. (Cords are represented as trees, with internal
* nodes representing concatenation and leaves consisting of either C
* strings or a functional description of the string.)
*
* The following are reasonable applications of cords. They would perform
* unacceptably if C strings were used:
* - A compiler that produces assembly language output by repeatedly
* concatenating instructions onto a cord representing the output file.
* - A text editor that converts the input file to a cord, and then
* performs editing operations by producing a new cord representing
* the file after each character change (and keeping the old ones in an
* edit history)
*
* For optimal performance, cords should be built by
* concatenating short sections.
* This interface is designed for maximum compatibility with C strings.
* ASCII NUL characters may be embedded in cords using CORD_from_fn.
* This is handled correctly, but CORD_to_char_star will produce a string
* with embedded NULs when given such a cord.
*
* This interface is fairly big, largely for performance reasons.
* The most basic constants and functions:
*
* CORD - the type of a cord;
* CORD_EMPTY - empty cord;
* CORD_len(cord) - length of a cord;
* CORD_cat(cord1,cord2) - concatenation of two cords;
* CORD_substr(cord, start, len) - substring (or subcord);
* CORD_pos i; CORD_FOR(i, cord) { ... CORD_pos_fetch(i) ... } -
* examine each character in a cord. CORD_pos_fetch(i) is the char.
* CORD_fetch(int i) - Retrieve i'th character (slowly).
* CORD_cmp(cord1, cord2) - compare two cords.
* CORD_from_file(FILE * f) - turn a read-only file into a cord.
* CORD_to_char_star(cord) - convert to C string.
* (Non-NULL C constant strings are cords.)
* CORD_printf (etc.) - cord version of printf. Use %r for cords.
*/
#ifndef CORD_H
#define CORD_H
#include <stddef.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(GC_DLL) && !defined(CORD_NOT_DLL)
/* Same as for GC_API in gc_config_macros.h. */
# ifdef CORD_BUILD
# if defined(__MINGW32__) || defined(__CEGCC__)
# define CORD_API __declspec(dllexport)
# elif defined(_MSC_VER) || defined(__DMC__) || defined(__BORLANDC__) \
|| defined(__CYGWIN__) || defined(__WATCOMC__)
# define CORD_API extern __declspec(dllexport)
# elif defined(__GNUC__) && !defined(GC_NO_VISIBILITY) \
&& (__GNUC__ >= 4 || defined(GC_VISIBILITY_HIDDEN_SET))
/* Only matters if used in conjunction with -fvisibility=hidden option. */
# define CORD_API extern __attribute__((__visibility__("default")))
# endif
# else
# if defined(__MINGW32__) || defined(__CEGCC__) || defined(_MSC_VER) \
|| defined(__DMC__) || defined(__BORLANDC__) || defined(__CYGWIN__)
# define CORD_API __declspec(dllimport)
# elif defined(__WATCOMC__)
# define CORD_API extern __declspec(dllimport)
# endif
# endif /* !CORD_BUILD */
#endif /* GC_DLL */
#ifndef CORD_API
# define CORD_API extern
#endif
/* Cords have type const char *. This is cheating quite a bit, and not */
/* 100% portable. But it means that nonempty character string */
/* constants may be used as cords directly, provided the string is */
/* never modified in place. The empty cord is represented by, and */
/* can be written as, 0. */
typedef const char * CORD;
/* An empty cord is always represented as nil */
#define CORD_EMPTY 0
/* Is a nonempty cord represented as a C string? */
#define CORD_IS_STRING(s) (*(s) != '\0')
/* Concatenate two cords. If the arguments are C strings, they may */
/* not be subsequently altered. */
CORD_API CORD CORD_cat(CORD x, CORD y);
/* Concatenate a cord and a C string with known length. Except for the */
/* empty string case, this is a special case of CORD_cat. Since the */
/* length is known, it can be faster. */
/* The string y is shared with the resulting CORD. Hence it should */
/* not be altered by the caller. */
CORD_API CORD CORD_cat_char_star(CORD x, const char * y, size_t leny);
/* Compute the length of a cord */
CORD_API size_t CORD_len(CORD x);
/* Cords may be represented by functions defining the ith character */
typedef char (* CORD_fn)(size_t i, void * client_data);
/* Turn a functional description into a cord. */
CORD_API CORD CORD_from_fn(CORD_fn fn, void * client_data, size_t len);
/* Return the substring (subcord really) of x with length at most n, */
/* starting at position i. (The initial character has position 0.) */
CORD_API CORD CORD_substr(CORD x, size_t i, size_t n);
/* Return the argument, but rebalanced to allow more efficient */
/* character retrieval, substring operations, and comparisons. */
/* This is useful only for cords that were built using repeated */
/* concatenation. Guarantees log time access to the result, unless */
/* x was obtained through a large number of repeated substring ops */
/* or the embedded functional descriptions take longer to evaluate. */
/* May reallocate significant parts of the cord. The argument is not */
/* modified; only the result is balanced. */
CORD_API CORD CORD_balance(CORD x);
/* The following traverse a cord by applying a function to each */
/* character. This is occasionally appropriate, especially where */
/* speed is crucial. But, since C doesn't have nested functions, */
/* clients of this sort of traversal are clumsy to write. Consider */
/* the functions that operate on cord positions instead. */
/* Function to iteratively apply to individual characters in cord. */
typedef int (* CORD_iter_fn)(char c, void * client_data);
/* Function to apply to substrings of a cord. Each substring is a */
/* a C character string, not a general cord. */
typedef int (* CORD_batched_iter_fn)(const char * s, void * client_data);
#define CORD_NO_FN ((CORD_batched_iter_fn)0)
/* Apply f1 to each character in the cord, in ascending order, */
/* starting at position i. If */
/* f2 is not CORD_NO_FN, then multiple calls to f1 may be replaced by */
/* a single call to f2. The parameter f2 is provided only to allow */
/* some optimization by the client. This terminates when the right */
/* end of this string is reached, or when f1 or f2 return != 0. In the */
/* latter case CORD_iter returns != 0. Otherwise it returns 0. */
/* The specified value of i must be < CORD_len(x). */
CORD_API int CORD_iter5(CORD x, size_t i, CORD_iter_fn f1,
CORD_batched_iter_fn f2, void * client_data);
/* A simpler version that starts at 0, and without f2: */
CORD_API int CORD_iter(CORD x, CORD_iter_fn f1, void * client_data);
#define CORD_iter(x, f1, cd) CORD_iter5(x, 0, f1, CORD_NO_FN, cd)
/* Similar to CORD_iter5, but end-to-beginning. No provisions for */
/* CORD_batched_iter_fn. */
CORD_API int CORD_riter4(CORD x, size_t i, CORD_iter_fn f1, void * client_data);
/* A simpler version that starts at the end: */
CORD_API int CORD_riter(CORD x, CORD_iter_fn f1, void * client_data);
#ifdef __cplusplus
} /* extern "C" */
#endif
/* Functions that operate on cord positions. The easy way to traverse */
/* cords. A cord position is logically a pair consisting of a cord */
/* and an index into that cord. But it is much faster to retrieve a */
/* character based on a position than on an index. Unfortunately, */
/* positions are big (order of a few 100 bytes), so allocate them with */
/* caution. */
/* Things in cord_pos.h should be treated as opaque, except as */
/* described below. Also note that */
/* CORD_pos_fetch, CORD_next and CORD_prev have both macro and function */
/* definitions. The former may evaluate their argument more than once. */
#include "cord_pos.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
Visible definitions from above:
typedef <OPAQUE but fairly big> CORD_pos[1];
* Extract the cord from a position:
CORD CORD_pos_to_cord(CORD_pos p);
* Extract the current index from a position:
size_t CORD_pos_to_index(CORD_pos p);
* Fetch the character located at the given position:
char CORD_pos_fetch(CORD_pos p);
* Initialize the position to refer to the given cord and index.
* Note that this is the most expensive function on positions:
void CORD_set_pos(CORD_pos p, CORD x, size_t i);
* Advance the position to the next character.
* P must be initialized and valid.
* Invalidates p if past end:
void CORD_next(CORD_pos p);
* Move the position to the preceding character.
* P must be initialized and valid.
* Invalidates p if past beginning:
void CORD_prev(CORD_pos p);
* Is the position valid, i.e. inside the cord?
int CORD_pos_valid(CORD_pos p);
*/
#define CORD_FOR(pos, cord) \
for (CORD_set_pos(pos, cord, 0); CORD_pos_valid(pos); CORD_next(pos))
/* An out of memory handler to call. May be supplied by client. */
/* Must not return. */
extern void (* CORD_oom_fn)(void);
/* Dump the representation of x to stdout in an implementation defined */
/* manner. Intended for debugging only. */
CORD_API void CORD_dump(CORD x);
/* The following could easily be implemented by the client. They are */
/* provided in cordxtra.c for convenience. */
/* Concatenate a character to the end of a cord. */
CORD_API CORD CORD_cat_char(CORD x, char c);
/* Concatenate n cords. */
CORD_API CORD CORD_catn(int n, /* CORD */ ...);
/* Return the character in CORD_substr(x, i, 1) */
CORD_API char CORD_fetch(CORD x, size_t i);
/* Return < 0, 0, or > 0, depending on whether x < y, x = y, x > y */
CORD_API int CORD_cmp(CORD x, CORD y);
/* A generalization that takes both starting positions for the */
/* comparison, and a limit on the number of characters to be compared. */
CORD_API int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start,
size_t len);
/* Find the first occurrence of s in x at position start or later. */
/* Return the position of the first character of s in x, or */
/* CORD_NOT_FOUND if there is none. */
CORD_API size_t CORD_str(CORD x, size_t start, CORD s);
/* Return a cord consisting of i copies of (possibly NUL) c. Dangerous */
/* in conjunction with CORD_to_char_star. */
/* The resulting representation takes constant space, independent of i. */
CORD_API CORD CORD_chars(char c, size_t i);
#define CORD_nul(i) CORD_chars('\0', (i))
/* Turn a file into cord. The file must be seekable. Its contents */
/* must remain constant. The file may be accessed as an immediate */
/* result of this call and/or as a result of subsequent accesses to */
/* the cord. Short files are likely to be immediately read, but */
/* long files are likely to be read on demand, possibly relying on */
/* stdio for buffering. */
/* We must have exclusive access to the descriptor f, i.e. we may */
/* read it at any time, and expect the file pointer to be */
/* where we left it. Normally this should be invoked as */
/* CORD_from_file(fopen(...)) */
/* CORD_from_file arranges to close the file descriptor when it is no */
/* longer needed (e.g. when the result becomes inaccessible). */
/* The file f must be such that ftell reflects the actual character */
/* position in the file, i.e. the number of characters that can be */
/* or were read with fread. On UNIX systems this is always true. On */
/* MS Windows systems, f must be opened in binary mode. */
CORD_API CORD CORD_from_file(FILE * f);
/* Equivalent to the above, except that the entire file will be read */
/* and the file pointer will be closed immediately. */
/* The binary mode restriction from above does not apply. */
CORD_API CORD CORD_from_file_eager(FILE * f);
/* Equivalent to the above, except that the file will be read on demand.*/
/* The binary mode restriction applies. */
CORD_API CORD CORD_from_file_lazy(FILE * f);
/* Turn a cord into a C string. The result shares no structure with */
/* x, and is thus modifiable. */
CORD_API char * CORD_to_char_star(CORD x);
/* Turn a C string into a CORD. The C string is copied, and so may */
/* subsequently be modified. */
CORD_API CORD CORD_from_char_star(const char *s);
/* Identical to the above, but the result may share structure with */
/* the argument and is thus not modifiable. */
CORD_API const char * CORD_to_const_char_star(CORD x);
/* Write a cord to a file, starting at the current position. No */
/* trailing NULs are newlines are added. */
/* Returns EOF if a write error occurs, 1 otherwise. */
CORD_API int CORD_put(CORD x, FILE * f);
/* "Not found" result for the following two functions. */
#define CORD_NOT_FOUND ((size_t)(-1))
/* A vague analog of strchr. Returns the position (an integer, not */
/* a pointer) of the first occurrence of (char) c inside x at position */
/* i or later. The value i must be < CORD_len(x). */
CORD_API size_t CORD_chr(CORD x, size_t i, int c);
/* A vague analog of strrchr. Returns index of the last occurrence */
/* of (char) c inside x at position i or earlier. The value i */
/* must be < CORD_len(x). */
CORD_API size_t CORD_rchr(CORD x, size_t i, int c);
#ifdef __cplusplus
} /* extern "C" */
#endif
/* The following are also not primitive, but are implemented in */
/* cordprnt.c. They provide functionality similar to the ANSI C */
/* functions with corresponding names, but with the following */
/* additions and changes: */
/* 1. A %r conversion specification specifies a CORD argument. Field */
/* width, precision, etc. have the same semantics as for %s. */
/* (Note that %c, %C, and %S were already taken.) */
/* 2. The format string is represented as a CORD. */
/* 3. CORD_sprintf and CORD_vsprintf assign the result through the 1st */
/* argument. Unlike their ANSI C versions, there is no need to guess */
/* the correct buffer size. */
/* 4. Most of the conversions are implement through the native */
/* vsprintf. Hence they are usually no faster, and */
/* idiosyncrasies of the native printf are preserved. However, */
/* CORD arguments to CORD_sprintf and CORD_vsprintf are NOT copied; */
/* the result shares the original structure. This may make them */
/* very efficient in some unusual applications. */
/* The format string is copied. */
/* All functions return the number of characters generated or -1 on */
/* error. This complies with the ANSI standard, but is inconsistent */
/* with some older implementations of sprintf. */
/* The implementation of these is probably less portable than the rest */
/* of this package. */
#ifndef CORD_NO_IO
#include <stdarg.h>
# ifdef __cplusplus
extern "C" {
# endif
CORD_API int CORD_sprintf(CORD * out, CORD format, ...);
CORD_API int CORD_vsprintf(CORD * out, CORD format, va_list args);
CORD_API int CORD_fprintf(FILE * f, CORD format, ...);
CORD_API int CORD_vfprintf(FILE * f, CORD format, va_list args);
CORD_API int CORD_printf(CORD format, ...);
CORD_API int CORD_vprintf(CORD format, va_list args);
# ifdef __cplusplus
} /* extern "C" */
# endif
#endif /* CORD_NO_IO */
#endif /* CORD_H */

View File

@ -0,0 +1,128 @@
/*
* Copyright (c) 1993-1994 by Xerox Corporation. All rights reserved.
*
* THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
* OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
*
* Permission is hereby granted to use or copy this program
* for any purpose, provided the above notices are retained on all copies.
* Permission to modify the code and to distribute modified code is granted,
* provided the above notices are retained, and a notice that the code was
* modified is included with the above copyright notice.
*/
/* This should never be included directly; included only from cord.h. */
#if !defined(CORD_POSITION_H) && defined(CORD_H)
#define CORD_POSITION_H
#ifdef __cplusplus
extern "C" {
#endif
/* The representation of CORD_position. This is private to the */
/* implementation, but the size is known to clients. Also */
/* the implementation of some exported macros relies on it. */
/* Don't use anything defined here and not in cord.h. */
# define MAX_DEPTH 48
/* The maximum depth of a balanced cord + 1. */
/* We don't let cords get deeper than MAX_DEPTH. */
struct CORD_pe {
CORD pe_cord;
size_t pe_start_pos;
};
/* A structure describing an entry on the path from the root */
/* to current position. */
typedef struct CORD_Pos {
size_t cur_pos;
int path_len;
# define CORD_POS_INVALID (0x55555555)
/* path_len == INVALID <==> position invalid */
const char *cur_leaf; /* Current leaf, if it is a string. */
/* If the current leaf is a function, */
/* then this may point to function_buf */
/* containing the next few characters. */
/* Always points to a valid string */
/* containing the current character */
/* unless cur_end is 0. */
size_t cur_start; /* Start position of cur_leaf */
size_t cur_end; /* Ending position of cur_leaf */
/* 0 if cur_leaf is invalid. */
struct CORD_pe path[MAX_DEPTH + 1];
/* path[path_len] is the leaf corresponding to cur_pos */
/* path[0].pe_cord is the cord we point to. */
# define FUNCTION_BUF_SZ 8
char function_buf[FUNCTION_BUF_SZ]; /* Space for next few chars */
/* from function node. */
} CORD_pos[1];
/* Extract the cord from a position: */
CORD_API CORD CORD_pos_to_cord(CORD_pos p);
/* Extract the current index from a position: */
CORD_API size_t CORD_pos_to_index(CORD_pos p);
/* Fetch the character located at the given position: */
CORD_API char CORD_pos_fetch(CORD_pos p);
/* Initialize the position to refer to the give cord and index. */
/* Note that this is the most expensive function on positions: */
CORD_API void CORD_set_pos(CORD_pos p, CORD x, size_t i);
/* Advance the position to the next character. */
/* P must be initialized and valid. */
/* Invalidates p if past end: */
CORD_API void CORD_next(CORD_pos p);
/* Move the position to the preceding character. */
/* P must be initialized and valid. */
/* Invalidates p if past beginning: */
CORD_API void CORD_prev(CORD_pos p);
/* Is the position valid, i.e. inside the cord? */
CORD_API int CORD_pos_valid(CORD_pos p);
CORD_API char CORD__pos_fetch(CORD_pos);
CORD_API void CORD__next(CORD_pos);
CORD_API void CORD__prev(CORD_pos);
#define CORD_pos_fetch(p) \
(((p)[0].cur_end != 0)? \
(p)[0].cur_leaf[(p)[0].cur_pos - (p)[0].cur_start] \
: CORD__pos_fetch(p))
#define CORD_next(p) \
(((p)[0].cur_pos + 1 < (p)[0].cur_end)? \
(p)[0].cur_pos++ \
: (CORD__next(p), 0))
#define CORD_prev(p) \
(((p)[0].cur_end != 0 && (p)[0].cur_pos > (p)[0].cur_start)? \
(p)[0].cur_pos-- \
: (CORD__prev(p), 0))
#define CORD_pos_to_index(p) ((p)[0].cur_pos)
#define CORD_pos_to_cord(p) ((p)[0].path[0].pe_cord)
#define CORD_pos_valid(p) ((p)[0].path_len != CORD_POS_INVALID)
/* Some grubby stuff for performance-critical friends: */
#define CORD_pos_chars_left(p) ((long)((p)[0].cur_end) - (long)((p)[0].cur_pos))
/* Number of characters in cache. <= 0 ==> none */
#define CORD_pos_advance(p,n) ((p)[0].cur_pos += (n) - 1, CORD_next(p))
/* Advance position by n characters */
/* 0 < n < CORD_pos_chars_left(p) */
#define CORD_pos_cur_char_addr(p) \
(p)[0].cur_leaf + ((p)[0].cur_pos - (p)[0].cur_start)
/* address of current character in cache. */
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More