aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/CONTRIBUTING.md215
-rw-r--r--.github/workflows/ci.yaml13
-rwxr-xr-xci/x86_64-macos-debug.sh58
-rwxr-xr-xci/x86_64-macos-release.sh (renamed from ci/x86_64-macos.sh)18
-rw-r--r--doc/docgen.zig18
-rw-r--r--doc/langref.html.in419
-rw-r--r--lib/std/build/InstallArtifactStep.zig4
-rw-r--r--lib/std/crypto/Certificate.zig18
-rw-r--r--lib/std/hash/crc.zig96
-rw-r--r--lib/std/hash/crc/catalog.zig903
-rw-r--r--lib/std/hash/crc/catalog_test.zig1237
-rw-r--r--lib/std/os.zig3
-rw-r--r--lib/std/os/windows.zig6
-rw-r--r--lib/std/zig/system/NativeTargetInfo.zig1
-rw-r--r--src/Compilation.zig94
-rw-r--r--src/Module.zig62
-rw-r--r--src/Package.zig39
-rw-r--r--src/Sema.zig16
-rw-r--r--src/link.zig1
-rw-r--r--src/main.zig26
-rw-r--r--src/test.zig1
-rw-r--r--tools/crc/catalog.txt113
-rw-r--r--tools/update_crc_catalog.zig169
23 files changed, 3020 insertions, 510 deletions
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 9a05b2b0f1..0148003d2a 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -1,212 +1,3 @@
-## Contributing
-
-### Start a Project Using Zig
-
-One of the best ways you can contribute to Zig is to start using it for a
-personal project. Here are some great examples:
-
- * [TM35-Metronome](https://github.com/TM35-Metronome) - tools for modifying and randomizing Pokémon games
- * [River](https://github.com/ifreund/river/) - a dynamic tiling wayland compositor
-
-More examples can be found on the
-[Community Projects Wiki](https://github.com/ziglang/zig/wiki/Community-Projects).
-
-Without fail, these projects lead to discovering bugs and helping flesh out use
-cases, which lead to further design iterations of Zig. Importantly, each issue
-found this way comes with real world motivations, so it is easy to explain
-your reasoning behind proposals and feature requests.
-
-Ideally, such a project will help you to learn new skills and add something
-to your personal portfolio at the same time.
-
-### Spread the Word
-
-Another way to contribute is to write about Zig, or speak about Zig at a
-conference, or do either of those things for your project which uses Zig.
-Here are some examples:
-
- * [Iterative Replacement of C with Zig](http://tiehuis.github.io/blog/zig1.html)
- * [The Right Tool for the Right Job: Redis Modules & Zig](https://www.youtube.com/watch?v=eCHM8-_poZY)
- * [Writing a small ray tracer in Rust and Zig](https://nelari.us/post/raytracer_with_rust_and_zig/)
-
-Zig is a brand new language, with no advertising budget. Word of mouth is the
-only way people find out about the project, and the more people hear about it,
-the more people will use it, and the better chance we have to take over the
-world.
-
-### Finding Contributor Friendly Issues
-
-Please note that issues labeled
-[Proposal](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aproposal)
-but do not also have the
-[Accepted](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3Aaccepted)
-label are still under consideration, and efforts to implement such a proposal
-have a high risk of being wasted. If you are interested in a proposal which is
-still under consideration, please express your interest in the issue tracker,
-providing extra insights and considerations that others have not yet expressed.
-The most highly regarded argument in such a discussion is a real world use case.
-
-The issue label
-[Contributor Friendly](https://github.com/ziglang/zig/issues?q=is%3Aissue+is%3Aopen+label%3A%22contributor+friendly%22)
-exists to help you find issues that are **limited in scope and/or
-knowledge of Zig internals.**
-
-### Editing Source Code
-
-First, build the Stage 1 compiler as described in
-[Building Zig From Source](https://github.com/ziglang/zig/wiki/Building-Zig-From-Source).
-
-Zig locates lib files relative to executable path by searching up the
-filesystem tree for a sub-path of `lib/zig/std/std.zig` or `lib/std/std.zig`.
-Typically the former is an install and the latter a git working tree which
-contains the build directory.
-
-During development it is not necessary to perform installs when modifying
-stage1 or userland sources and in fact it is faster and simpler to run,
-test and debug from a git working tree.
-
-- `make` is typically sufficient to build zig during development iterations.
-- `make install` performs a build __and__ install.
-- `msbuild -p:Configuration=Release INSTALL.vcxproj` on Windows performs a
-build and install. To avoid install, pass cmake option `-DZIG_NO_LIB=ON`.
-
-To test changes, do the following from the build directory:
-
-1. Run `make` (on POSIX) or
- `msbuild -p:Configuration=Release INSTALL.vcxproj` (on Windows).
-2. `$BUILD_DIR/zig build test` (on POSIX) or
- `$BUILD_DIR/Release\zig.exe build test` (on Windows).
-
-That runs the whole test suite, which does a lot of extra testing that you
-likely won't always need, and can take upwards of 1 hour. This is what the
-CI server runs when you make a pull request. (Note: actually it runs a few
-more tests; keep reading.)
-
-To save time, you can add the `--help` option to the `zig build` command and
-see what options are available. One of the most helpful ones is
-`-Dskip-release`. Adding this option to the command in step 2 above will take
-the time down from around 2 hours to about 6 minutes, and this is a good
-enough amount of testing before making a pull request.
-
-Another example is choosing a different set of things to test. For example,
-`test-std` instead of `test` will only run the standard library tests, and
-not the other ones. Combining this suggestion with the previous one, you could
-do this:
-
-`$BUILD_DIR/bin/zig build test-std -Dskip-release` (on POSIX) or
-`$BUILD_DIR/Release\zig.exe build test-std -Dskip-release` (on Windows).
-
-This will run only the standard library tests, in debug mode only, for all
-targets (it will cross-compile the tests for non-native targets but not run
-them).
-
-When making changes to the compiler source code, the most helpful test step to
-run is `test-behavior`. When editing documentation it is `docs`. You can find
-this information and more in the `--help` menu.
-
-#### Testing Changes to std lib
-
-To quickly test a change to a file in the standard library, you can run zig test and specify a custom lib directory with the follow command-line argument.
-
-```bash
-./build/zig test lib/std/fmt.zig --zig-lib-dir lib --main-pkg-path lib/std
-```
-
-#### Testing Non-Native Architectures with QEMU
-
-The Linux CI server additionally has qemu installed and sets `-fqemu`.
-This provides test coverage for, e.g. aarch64 even on x86_64 machines. It's
-recommended for Linux users to install qemu and enable this testing option
-when editing the standard library or anything related to a non-native
-architecture.
-
-##### glibc
-
-Testing foreign architectures with dynamically linked glibc is one step trickier.
-This requires enabling `--glibc-runtimes /path/to/glibc/multi/install/glibcs`.
-This path is obtained by building glibc for multiple architectures. This
-process for me took an entire day to complete and takes up 65 GiB on my hard
-drive. The CI server does not provide this test coverage. Instructions for
-producing this path can be found
-[on the wiki](https://github.com/ziglang/zig/wiki/Updating-libc#glibc).
-Just the part with `build-many-glibcs.py`.
-
-It's understood that most contributors will not have these tests enabled.
-
-#### Testing Windows from a Linux Machine with Wine
-
-When developing on Linux, another option is available to you: `-fwine`.
-This will enable running behavior tests and std lib tests with Wine. It's
-recommended for Linux users to install Wine and enable this testing option
-when editing the standard library or anything Windows-related.
-
-#### Testing WebAssembly using wasmtime
-
-If you have [wasmtime](https://wasmtime.dev/) installed, take advantage of the
-`-fwasmtime` flag which will enable running WASI behavior tests and std
-lib tests. It's recommended for all users to install wasmtime and enable this
-testing option when editing the standard library and especially anything
-WebAssembly-related.
-
-#### Improving Translate-C
-
-Please read the [Editing Source Code](#editing-source-code) section as a
-prerequisite to this one.
-
-`translate-c` is a feature provided by Zig that converts C source code into
-Zig source code. It powers the `zig translate-c` command as well as
-[@cImport](https://ziglang.org/documentation/master/#cImport), allowing Zig
-code to not only take advantage of function prototypes defined in .h files,
-but also `static inline` functions written in C, and even some macros.
-
-This feature works by using libclang API to parse and semantically analyze
-C/C++ files, and then based on the provided AST and type information,
-generating Zig AST, and finally using the mechanisms of `zig fmt` to render
-the Zig AST to a file.
-
-The relevant tests for this feature are:
-
- * `test/run_translated_c.zig` - each test case is C code with a `main` function. The C code
- is translated into Zig code, compiled, and run, and tests that the expected output is the
- same, and that the program exits cleanly. This kind of test coverage is preferred, when
- possible, because it makes sure that the resulting Zig code is actually viable.
-
- * `test/stage1/behavior/translate_c_macros.zig` - each test case consists of a Zig test
- which checks that the relevant macros in `test/stage1/behavior/translate_c_macros.h`.
- have the correct values. Macros have to be tested separately since they are expanded by
- Clang in `run_translated_c` tests.
-
- * `test/translate_c.zig` - each test case is C code, with a list of expected strings which
- must be found in the resulting Zig code. This kind of test is more precise in what it
- measures, but does not provide test coverage of whether the resulting Zig code is valid.
-
-This feature is self-hosted, even though Zig is not fully self-hosted yet. In the Zig source
-repo, we maintain a C API on top of Clang's C++ API:
-
- * `src/zig_clang.h` - the C API that we maintain on top of Clang's C++ API. This
- file does not include any Clang's C++ headers. Instead, C types and C enums are defined
- here.
-
- * `src/zig_clang.cpp` - a lightweight wrapper that fulfills the C API on top of the
- C++ API. It takes advantage of `static_assert` to make sure we get compile errors when
- Clang's C++ API changes. This one file necessarily does include Clang's C++ headers, which
- makes it the slowest-to-compile source file in all of Zig's codebase.
-
- * `src/clang.zig` - the Zig equivalent of `src/zig_clang.h`. This is a manually
- maintained list of types and functions that are ABI-compatible with the Clang C API we
- maintain. In theory this could be generated by running translate-c on `src/zig_clang.h`,
- but that would introduce a dependency cycle, since we are using this file to implement
- translate-c.
-
-Finally, the actual source code for the translate-c feature is
-`src/translate_c.zig`. This code uses the Clang C API exposed by
-`src/clang.zig`, and produces Zig AST.
-
-The steps for contributing to translate-c look like this:
-
- 1. Identify a test case you want to improve. Add it as a run-translated-c test
- case (usually preferable), or as a translate-c test case.
-
- 2. Edit `src/translate_c.zig` to improve the behavior.
-
- 3. Run the relevant tests: `./zig build test-run-translated-c test-translate-c`
+Please see the
+[Contributing](https://github.com/ziglang/zig/wiki/Contributing)
+page on the wiki.
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index a0ff406dec..34e029cdd5 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -38,7 +38,7 @@ jobs:
uses: actions/checkout@v3
- name: Build and Test
run: sh ci/aarch64-linux-release.sh
- x86_64-macos:
+ x86_64-macos-debug:
runs-on: "macos-11"
env:
ARCH: "x86_64"
@@ -46,7 +46,16 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- name: Build and Test
- run: ci/x86_64-macos.sh
+ run: ci/x86_64-macos-debug.sh
+ x86_64-macos-release:
+ runs-on: "macos-11"
+ env:
+ ARCH: "x86_64"
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+ - name: Build and Test
+ run: ci/x86_64-macos-release.sh
aarch64-macos:
runs-on: [self-hosted, macOS, aarch64]
env:
diff --git a/ci/x86_64-macos-debug.sh b/ci/x86_64-macos-debug.sh
new file mode 100755
index 0000000000..c24ff5d295
--- /dev/null
+++ b/ci/x86_64-macos-debug.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+set -x
+set -e
+
+ZIGDIR="$(pwd)"
+TARGET="$ARCH-macos-none"
+MCPU="baseline"
+CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1416+8484df5bd"
+PREFIX="$HOME/$CACHE_BASENAME"
+JOBS="-j3"
+
+rm -rf $PREFIX
+cd $HOME
+
+curl -L -O "https://ziglang.org/deps/$CACHE_BASENAME.tar.xz"
+tar xf "$CACHE_BASENAME.tar.xz"
+
+ZIG="$PREFIX/bin/zig"
+
+cd $ZIGDIR
+
+# Make the `zig version` number consistent.
+# This will affect the cmake command below.
+git config core.abbrev 9
+git fetch --unshallow || true
+git fetch --tags
+
+rm -rf build
+mkdir build
+cd build
+
+# Override the cache directories because they won't actually help other CI runs
+# which will be testing alternate versions of zig, and ultimately would just
+# fill up space on the hard drive for no reason.
+export ZIG_GLOBAL_CACHE_DIR="$(pwd)/zig-global-cache"
+export ZIG_LOCAL_CACHE_DIR="$(pwd)/zig-local-cache"
+
+cmake .. \
+ -DCMAKE_PREFIX_PATH="$PREFIX" \
+ -DCMAKE_BUILD_TYPE=Debug \
+ -DCMAKE_C_COMPILER="$ZIG;cc;-target;$TARGET;-mcpu=$MCPU" \
+ -DCMAKE_CXX_COMPILER="$ZIG;c++;-target;$TARGET;-mcpu=$MCPU" \
+ -DZIG_TARGET_TRIPLE="$TARGET" \
+ -DZIG_TARGET_MCPU="$MCPU" \
+ -DZIG_STATIC=ON
+
+make $JOBS install
+
+stage3/bin/zig build test docs \
+ --zig-lib-dir "$(pwd)/../lib" \
+ -Denable-macos-sdk \
+ -Dstatic-llvm \
+ -Dskip-non-native \
+ --search-prefix "$PREFIX"
+
+# Produce the experimental std lib documentation.
+stage3/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib
diff --git a/ci/x86_64-macos.sh b/ci/x86_64-macos-release.sh
index 4ea62bf1e0..a4dedb4446 100755
--- a/ci/x86_64-macos.sh
+++ b/ci/x86_64-macos-release.sh
@@ -3,13 +3,10 @@
set -x
set -e
-# Script assumes the presence of the following:
-# s3cmd
-
ZIGDIR="$(pwd)"
TARGET="$ARCH-macos-none"
MCPU="baseline"
-CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.534+b0b1cc356"
+CACHE_BASENAME="zig+llvm+lld+clang-$TARGET-0.11.0-dev.1416+8484df5bd"
PREFIX="$HOME/$CACHE_BASENAME"
JOBS="-j3"
@@ -40,7 +37,6 @@ export ZIG_GLOBAL_CACHE_DIR="$(pwd)/zig-global-cache"
export ZIG_LOCAL_CACHE_DIR="$(pwd)/zig-local-cache"
cmake .. \
- -DCMAKE_INSTALL_PREFIX="stage3-release" \
-DCMAKE_PREFIX_PATH="$PREFIX" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$ZIG;cc;-target;$TARGET;-mcpu=$MCPU" \
@@ -51,7 +47,7 @@ cmake .. \
make $JOBS install
-stage3-release/bin/zig build test docs \
+stage3/bin/zig build test docs \
--zig-lib-dir "$(pwd)/../lib" \
-Denable-macos-sdk \
-Dstatic-llvm \
@@ -59,20 +55,20 @@ stage3-release/bin/zig build test docs \
--search-prefix "$PREFIX"
# Produce the experimental std lib documentation.
-stage3-release/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib
+stage3/bin/zig test ../lib/std/std.zig -femit-docs -fno-emit-bin --zig-lib-dir ../lib
# Ensure that stage3 and stage4 are byte-for-byte identical.
-stage3-release/bin/zig build \
- --prefix stage4-release \
+stage3/bin/zig build \
+ --prefix stage4 \
-Denable-llvm \
-Dno-lib \
-Drelease \
-Dstrip \
-Dtarget=$TARGET \
-Duse-zig-libcxx \
- -Dversion-string="$(stage3-release/bin/zig version)"
+ -Dversion-string="$(stage3/bin/zig version)"
# diff returns an error code if the files differ.
echo "If the following command fails, it means nondeterminism has been"
echo "introduced, making stage3 and stage4 no longer byte-for-byte identical."
-diff stage3-release/bin/zig stage4-release/bin/zig
+diff stage3/bin/zig stage4/bin/zig
diff --git a/doc/docgen.zig b/doc/docgen.zig
index 3ec961802c..82fafe2b64 100644
--- a/doc/docgen.zig
+++ b/doc/docgen.zig
@@ -539,12 +539,15 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
} else if (mem.eql(u8, tag_name, "code_begin")) {
_ = try eatToken(tokenizer, Token.Id.Separator);
const code_kind_tok = try eatToken(tokenizer, Token.Id.TagContent);
- var name: []const u8 = "test";
+ _ = try eatToken(tokenizer, Token.Id.Separator);
+ const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
+ const name = tokenizer.buffer[name_tok.start..name_tok.end];
+ var error_str: []const u8 = "";
const maybe_sep = tokenizer.next();
switch (maybe_sep.id) {
Token.Id.Separator => {
- const name_tok = try eatToken(tokenizer, Token.Id.TagContent);
- name = tokenizer.buffer[name_tok.start..name_tok.end];
+ const error_tok = try eatToken(tokenizer, Token.Id.TagContent);
+ error_str = tokenizer.buffer[error_tok.start..error_tok.end];
_ = try eatToken(tokenizer, Token.Id.BracketClose);
},
Token.Id.BracketClose => {},
@@ -562,16 +565,13 @@ fn genToc(allocator: Allocator, tokenizer: *Tokenizer) !Toc {
} else if (mem.eql(u8, code_kind_str, "test")) {
code_kind_id = Code.Id.Test;
} else if (mem.eql(u8, code_kind_str, "test_err")) {
- code_kind_id = Code.Id{ .TestError = name };
- name = "test";
+ code_kind_id = Code.Id{ .TestError = error_str };
} else if (mem.eql(u8, code_kind_str, "test_safety")) {
- code_kind_id = Code.Id{ .TestSafety = name };
- name = "test";
+ code_kind_id = Code.Id{ .TestSafety = error_str };
} else if (mem.eql(u8, code_kind_str, "obj")) {
code_kind_id = Code.Id{ .Obj = null };
} else if (mem.eql(u8, code_kind_str, "obj_err")) {
- code_kind_id = Code.Id{ .Obj = name };
- name = "test";
+ code_kind_id = Code.Id{ .Obj = error_str };
} else if (mem.eql(u8, code_kind_str, "lib")) {
code_kind_id = Code.Id.Lib;
} else if (mem.eql(u8, code_kind_str, "syntax")) {
diff --git a/doc/langref.html.in b/doc/langref.html.in
index ef2b6b9710..c06f40366c 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -333,7 +333,6 @@
content: "";
}
}
- }
</style>
</head>
<body>
@@ -351,7 +350,7 @@
<a href="https://ziglang.org/documentation/0.7.1/">0.7.1</a> |
<a href="https://ziglang.org/documentation/0.8.1/">0.8.1</a> |
<a href="https://ziglang.org/documentation/0.9.1/">0.9.1</a> |
- <a href="https://ziglang.org/documentation/0.10.0/">0.10.0</a> |
+ <a href="https://ziglang.org/documentation/0.10.1/">0.10.1</a> |
master
</nav>
<nav aria-labelledby="table-of-contents">
@@ -1039,7 +1038,7 @@ pub fn main() void {
<p>
Code written within one or more {#syntax#}test{#endsyntax#} declarations can be used to ensure behavior meets expectations:
</p>
- {#code_begin|test|introducing_zig_test#}
+ {#code_begin|test|testing_introduction#}
const std = @import("std");
test "expect addOne adds one to 41" {
@@ -1124,13 +1123,13 @@ fn addOne(number: i32) i32 {
syntax. This syntax tells the compiler to ignore the result of the expression on the right side of the
assignment operator.
</p>
- {#code_begin|test|testdecl_container_top_level#}
+ {#code_begin|test|testing_nested_container_tests#}
const std = @import("std");
const expect = std.testing.expect;
// Imported source file tests will run when referenced from a top-level test declaration.
// The next line alone does not cause "introducing_zig_test.zig" tests to run.
-const imported_file = @import("introducing_zig_test.zig");
+const imported_file = @import("testing_introduction.zig");
test {
// To run nested container tests, either, call `refAllDecls` which will
@@ -1143,7 +1142,7 @@ test {
// The `_ = C;` syntax is a no-op reference to the identifier `C`.
_ = S;
_ = U;
- _ = @import("introducing_zig_test.zig");
+ _ = @import("testing_introduction.zig");
}
const S = struct {
@@ -1184,7 +1183,7 @@ const U = union { // U is referenced by the file's top-level test declaration
When a test returns an error, the test is considered a failure and its {#link|error return trace|Error Return Traces#}
is output to standard error. The total number of failures will be reported after all tests have run.
</p>
- {#code_begin|test_err#}
+ {#code_begin|test_err|testing_failure#}
const std = @import("std");
test "expect this to fail" {
@@ -1208,7 +1207,7 @@ test "expect this to succeed" {
{#syntax#}error.SkipZigTest{#endsyntax#} and the default test runner will consider the test as being skipped.
The total number of skipped tests will be reported after all tests have run.
</p>
- {#code_begin|test#}
+ {#code_begin|test|testing_skip#}
test "this will be skipped" {
return error.SkipZigTest;
}
@@ -1221,7 +1220,7 @@ test "this will be skipped" {
{#syntax#}std.testing.allocator{#endsyntax#}, the default test runner will report any leaks that are
found from using the testing allocator:
</p>
- {#code_begin|test_err|1 tests leaked memory#}
+ {#code_begin|test_err|testing_detect_leak|1 tests leaked memory#}
const std = @import("std");
test "detect leak" {
@@ -1239,7 +1238,7 @@ test "detect leak" {
Use the {#link|compile variable|Compile Variables#} {#syntax#}@import("builtin").is_test{#endsyntax#}
to detect a test build:
</p>
- {#code_begin|test|detect_test#}
+ {#code_begin|test|testing_detect_test#}
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
@@ -1264,7 +1263,7 @@ fn isATest() bool {
you create tests. In addition to the <code>expect</code> function, this document uses a couple of more functions
as exemplified here:
</p>
- {#code_begin|test|testing_functions#}
+ {#code_begin|test|testing_namespace#}
const std = @import("std");
test "expectEqual demo" {
@@ -1319,7 +1318,7 @@ test "expectError demo" {
<p>
If a name that does not fit these requirements is needed, such as for linking with external libraries, the {#syntax#}@""{#endsyntax#} syntax may be used.
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|identifiers#}
const @"identifier with spaces in it" = 0xff;
const @"1SmallStep4Man" = 112358;
@@ -1342,7 +1341,7 @@ const color: Color = .@"really red";
{#link|comptime#}. If a container level variable is {#syntax#}const{#endsyntax#} then its value is
{#syntax#}comptime{#endsyntax#}-known, otherwise it is runtime-known.
</p>
- {#code_begin|test|container_level_variables#}
+ {#code_begin|test|test_container_level_variables#}
var y: i32 = add(10, x);
const x: i32 = add(12, 34);
@@ -1361,7 +1360,7 @@ const expect = std.testing.expect;
<p>
Container level variables may be declared inside a {#link|struct#}, {#link|union#}, {#link|enum#}, or {#link|opaque#}:
</p>
- {#code_begin|test|namespaced_container_level_variable#}
+ {#code_begin|test|test_namespaced_container_level_variable#}
const std = @import("std");
const expect = std.testing.expect;
@@ -1385,7 +1384,7 @@ fn foo() i32 {
<p>
It is also possible to have local variables with static lifetime by using containers inside functions.
</p>
- {#code_begin|test|static_local_variable#}
+ {#code_begin|test|test_static_local_variable#}
const std = @import("std");
const expect = std.testing.expect;
@@ -1414,7 +1413,7 @@ fn foo() i32 {
{#header_open|Thread Local Variables#}
<p>A variable may be specified to be a thread-local variable using the
{#syntax#}threadlocal{#endsyntax#} keyword:</p>
- {#code_begin|test|tls#}
+ {#code_begin|test|test_thread_local_variables#}
const std = @import("std");
const assert = std.debug.assert;
@@ -1458,7 +1457,7 @@ fn testTls() void {
All variables declared in a {#syntax#}comptime{#endsyntax#} expression are implicitly
{#syntax#}comptime{#endsyntax#} variables.
</p>
- {#code_begin|test|comptime_vars#}
+ {#code_begin|test|test_comptime_variables#}
const std = @import("std");
const expect = std.testing.expect;
@@ -1582,7 +1581,7 @@ const nan = std.math.nan(f128);
{#header_open|Floating Point Operations#}
<p>By default floating point operations use {#syntax#}Strict{#endsyntax#} mode,
but you can switch to {#syntax#}Optimized{#endsyntax#} mode on a per-block basis:</p>
- {#code_begin|obj|foo#}
+ {#code_begin|obj|float_mode_obj#}
{#code_release_fast#}
{#code_disable_cache#}
const std = @import("std");
@@ -1600,8 +1599,8 @@ export fn foo_optimized(x: f64) f64 {
<p>For this test we have to separate code into two object files -
otherwise the optimizer figures out all the values at compile-time,
which operates in strict mode.</p>
- {#code_begin|exe|float_mode#}
- {#code_link_object|foo#}
+ {#code_begin|exe|float_mode_exe#}
+ {#code_link_object|float_mode_obj#}
const print = @import("std").debug.print;
extern fn foo_strict(x: f64) f64;
@@ -2326,7 +2325,7 @@ or
{#header_close#}
{#header_close#}
{#header_open|Arrays#}
- {#code_begin|test|arrays#}
+ {#code_begin|test|test_arrays#}
const expect = @import("std").testing.expect;
const assert = @import("std").debug.assert;
const mem = @import("std").mem;
@@ -2437,7 +2436,7 @@ test "array initialization with function calls" {
<p>
Multidimensional arrays can be created by nesting arrays:
</p>
- {#code_begin|test|multidimensional#}
+ {#code_begin|test|test_multidimensional_arrays#}
const std = @import("std");
const expect = std.testing.expect;
@@ -2468,7 +2467,7 @@ test "multidimensional arrays" {
The syntax {#syntax#}[N:x]T{#endsyntax#} describes an array which has a sentinel element of value {#syntax#}x{#endsyntax#} at the
index corresponding to {#syntax#}len{#endsyntax#}.
</p>
- {#code_begin|test|null_terminated_array#}
+ {#code_begin|test|test_null_terminated_array#}
const std = @import("std");
const expect = std.testing.expect;
@@ -2521,7 +2520,7 @@ test "null terminated array" {
although small powers of two (2-64) are most typical. Note that excessively long vector lengths (e.g. 2^20) may
result in compiler crashes on current versions of Zig.
</p>
- {#code_begin|test|vector_example#}
+ {#code_begin|test|test_vector#}
const std = @import("std");
const expectEqual = std.testing.expectEqual;
@@ -2609,7 +2608,7 @@ test "Conversion between vectors, arrays, and slices" {
</li>
</ul>
<p>Use {#syntax#}&x{#endsyntax#} to obtain a single-item pointer:</p>
- {#code_begin|test|single_item_pointer_test#}
+ {#code_begin|test|test_single_item_pointer#}
const expect = @import("std").testing.expect;
test "address of syntax" {
@@ -2647,7 +2646,7 @@ test "pointer array access" {
<p>
Zig supports pointer arithmetic. It's better to assign the pointer to {#syntax#}[*]T{#endsyntax#} and increment that variable. For example, directly incrementing the pointer from a slice will corrupt it.
</p>
- {#code_begin|test|pointer_arthemtic#}
+ {#code_begin|test|test_pointer_arithmetic#}
const expect = @import("std").testing.expect;
test "pointer arithmetic with many-item pointer" {
@@ -2683,7 +2682,7 @@ test "pointer arithmetic with slices" {
against this kind of undefined behavior. This is one reason
we prefer slices to pointers.
</p>
- {#code_begin|test|slice_bounds#}
+ {#code_begin|test|test_slice_bounds#}
const expect = @import("std").testing.expect;
test "pointer slicing" {
@@ -2699,7 +2698,7 @@ test "pointer slicing" {
{#code_end#}
<p>Pointers work at compile-time too, as long as the code does not depend on
an undefined memory layout:</p>
- {#code_begin|test|comptime_pointers#}
+ {#code_begin|test|test_comptime_pointers#}
const expect = @import("std").testing.expect;
test "comptime pointers" {
@@ -2714,7 +2713,7 @@ test "comptime pointers" {
{#code_end#}
<p>To convert an integer address into a pointer, use {#syntax#}@intToPtr{#endsyntax#}.
To convert a pointer to an integer, use {#syntax#}@ptrToInt{#endsyntax#}:</p>
- {#code_begin|test|integer_pointer_conversion#}
+ {#code_begin|test|test_integer_pointer_conversion#}
const expect = @import("std").testing.expect;
test "@ptrToInt and @intToPtr" {
@@ -2726,7 +2725,7 @@ test "@ptrToInt and @intToPtr" {
{#code_end#}
<p>Zig is able to preserve memory addresses in comptime code, as long as
the pointer is never dereferenced:</p>
- {#code_begin|test|comptime_pointer_conversion#}
+ {#code_begin|test|test_comptime_pointer_conversion#}
const expect = @import("std").testing.expect;
test "comptime @intToPtr" {
@@ -2746,7 +2745,7 @@ test "comptime @intToPtr" {
should have side effects, such as Memory Mapped Input/Output (MMIO), use {#syntax#}volatile{#endsyntax#}.
In the following code, loads and stores with {#syntax#}mmio_ptr{#endsyntax#} are guaranteed to all happen
and in the same order as in source code:</p>
- {#code_begin|test|volatile#}
+ {#code_begin|test|test_volatile#}
const expect = @import("std").testing.expect;
test "volatile" {
@@ -2765,7 +2764,7 @@ test "volatile" {
operation that Zig cannot protect you against. Use {#syntax#}@ptrCast{#endsyntax#} only when other
conversions are not possible.
</p>
- {#code_begin|test|pointer_casting#}
+ {#code_begin|test|test_pointer_casting#}
const std = @import("std");
const expect = std.testing.expect;
@@ -2803,7 +2802,7 @@ test "pointer child type" {
In Zig, a pointer type has an alignment value. If the value is equal to the
alignment of the underlying type, it can be omitted from the type:
</p>
- {#code_begin|test|variable_alignment#}
+ {#code_begin|test|test_variable_alignment#}
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
@@ -2826,7 +2825,7 @@ test "variable alignment" {
You can specify alignment on variables and functions. If you do this, then
pointers to them get the specified alignment:
</p>
- {#code_begin|test|variable_func_alignment#}
+ {#code_begin|test|test_variable_func_alignment#}
const expect = @import("std").testing.expect;
var foo: u8 align(4) = 100;
@@ -2860,7 +2859,7 @@ test "function alignment" {
pointer into a more aligned pointer. This is a no-op at runtime, but inserts a
{#link|safety check|Incorrect Pointer Alignment#}:
</p>
- {#code_begin|test_safety|incorrect alignment#}
+ {#code_begin|test_safety|test_incorrect_pointer_alignment|incorrect alignment#}
const std = @import("std");
test "pointer alignment safety" {
@@ -2885,7 +2884,7 @@ fn foo(bytes: []u8) u32 {
did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a
{#link|Pointer Cast Invalid Null#} panic:
</p>
- {#code_begin|test|allowzero#}
+ {#code_begin|test|test_allowzero#}
const std = @import("std");
const expect = std.testing.expect;
@@ -2903,7 +2902,7 @@ test "allowzero" {
has a length determined by a sentinel value. This provides protection
against buffer overflow and overreads.
</p>
- {#code_begin|exe_build_err#}
+ {#code_begin|exe_build_err|sentinel-terminated_pointer#}
{#link_libc#}
const std = @import("std");
@@ -2923,7 +2922,7 @@ pub fn main() anyerror!void {
{#header_close#}
{#header_open|Slices#}
- {#code_begin|test_safety|index out of bounds#}
+ {#code_begin|test_safety|test_basic_slices|index out of bounds#}
const expect = @import("std").testing.expect;
test "basic slices" {
@@ -2958,7 +2957,7 @@ test "basic slices" {
}
{#code_end#}
<p>This is one reason we prefer slices to pointers.</p>
- {#code_begin|test|slices#}
+ {#code_begin|test|test_slices#}
const std = @import("std");
const expect = std.testing.expect;
const mem = std.mem;
@@ -3019,7 +3018,7 @@ test "slice pointer" {
guarantee that there are no sentinel elements before that. Sentinel-terminated slices allow element
access to the {#syntax#}len{#endsyntax#} index.
</p>
- {#code_begin|test|null_terminated_slice#}
+ {#code_begin|test|test_null_terminated_slice#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3035,7 +3034,7 @@ test "null terminated slice" {
{#syntax#}data[start..end :x]{#endsyntax#}, where {#syntax#}data{#endsyntax#} is a many-item pointer,
array or slice and {#syntax#}x{#endsyntax#} is the sentinel value.
</p>
- {#code_begin|test|null_terminated_slicing#}
+ {#code_begin|test|test_null_terminated_slicing#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3052,7 +3051,7 @@ test "null terminated slicing" {
Sentinel-terminated slicing asserts that the element in the sentinel position of the backing data is
actually the sentinel value. If this is not the case, safety-protected {#link|Undefined Behavior#} results.
</p>
- {#code_begin|test_safety|sentinel mismatch#}
+ {#code_begin|test_safety|test_sentinel_mismatch|sentinel mismatch#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3074,7 +3073,7 @@ test "sentinel mismatch" {
{#header_close#}
{#header_open|struct#}
- {#code_begin|test|structs#}
+ {#code_begin|test|test_structs#}
// Declare a struct.
// Zig gives no guarantees about the order of fields and the size of
// the struct but the fields are guaranteed to be ABI-aligned.
@@ -3223,7 +3222,7 @@ test "linked list" {
Each struct field may have an expression indicating the default field value. Such expressions
are executed at {#link|comptime#}, and allow the field to be omitted in a struct literal expression:
</p>
- {#code_begin|test|default_field_values#}
+ {#code_begin|test|test_struct_default_field_values#}
const Foo = struct {
a: i32 = 1234,
b: i32,
@@ -3272,7 +3271,7 @@ test "default struct initialization fields" {
in a {#link|@bitCast#} or a {#link|@ptrCast#} to reinterpret memory.
This even works at {#link|comptime#}:
</p>
- {#code_begin|test|packed_structs#}
+ {#code_begin|test|test_packed_structs#}
const std = @import("std");
const native_endian = @import("builtin").target.cpu.arch.endian();
const expect = std.testing.expect;
@@ -3316,7 +3315,7 @@ fn doTheTest() !void {
<p>
Zig allows the address to be taken of a non-byte-aligned field:
</p>
- {#code_begin|test|pointer_to_non-byte_aligned_field#}
+ {#code_begin|test|test_pointer_to_non-byte_aligned_field#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3341,7 +3340,7 @@ test "pointer to non-byte-aligned field" {
However, the pointer to a non-byte-aligned field has special properties and cannot
be passed when a normal pointer is expected:
</p>
- {#code_begin|test_err|expected type#}
+ {#code_begin|test_err|test_misaligned_pointer|expected type#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3372,7 +3371,7 @@ fn bar(x: *const u3) u3 {
<p>
Pointers to non-ABI-aligned fields share the same address as the other fields within their host integer:
</p>
- {#code_begin|test|packed_struct_field_addrs#}
+ {#code_begin|test|test_packed_struct_field_address#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3422,7 +3421,7 @@ test "pointer to non-bit-aligned field" {
Packed structs have the same alignment as their backing integer, however, overaligned
pointers to packed structs can override this:
</p>
- {#code_begin|test|overaligned_packed_struct#}
+ {#code_begin|test|test_overaligned_packed_struct#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3501,7 +3500,7 @@ fn List(comptime T: type) type {
the struct literal will directly instantiate the {#link|result location|Result Location Semantics#},
with no copy:
</p>
- {#code_begin|test|struct_result#}
+ {#code_begin|test|test_struct_result#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3520,7 +3519,7 @@ test "anonymous struct literal" {
The struct type can be inferred. Here the {#link|result location|Result Location Semantics#}
does not include a type, and so Zig infers the type:
</p>
- {#code_begin|test|struct_anon#}
+ {#code_begin|test|test_anonymous_struct#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3557,7 +3556,7 @@ fn dump(args: anytype) !void {
Like arrays, tuples have a .len field, can be indexed (provided the index is comptime-known)
and work with the ++ and ** operators. They can also be iterated over with {#link|inline for#}.
</p>
- {#code_begin|test|tuple#}
+ {#code_begin|test|test_tuples#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3582,7 +3581,7 @@ test "tuple" {
{#see_also|comptime|@fieldParentPtr#}
{#header_close#}
{#header_open|enum#}
- {#code_begin|test|enums#}
+ {#code_begin|test|test_enums#}
const expect = @import("std").testing.expect;
const mem = @import("std").mem;
@@ -3700,7 +3699,7 @@ test "@tagName" {
<p>
By default, enums are not guaranteed to be compatible with the C ABI:
</p>
- {#code_begin|obj_err|parameter of type 'test.Foo' not allowed in function with calling convention 'C'#}
+ {#code_begin|obj_err|enum_export_error|parameter of type 'enum_export_error.Foo' not allowed in function with calling convention 'C'#}
const Foo = enum { a, b, c };
export fn entry(foo: Foo) void { _ = foo; }
{#code_end#}
@@ -3708,7 +3707,7 @@ export fn entry(foo: Foo) void { _ = foo; }
For a C-ABI-compatible enum, provide an explicit tag type to
the enum:
</p>
- {#code_begin|obj#}
+ {#code_begin|obj|enum_export#}
const Foo = enum(c_int) { a, b, c };
export fn entry(foo: Foo) void { _ = foo; }
{#code_end#}
@@ -3801,7 +3800,7 @@ test "switch on non-exhaustive enum" {
{#link|Accessing the non-active field|Wrong Union Field Access#} is
safety-checked {#link|Undefined Behavior#}:
</p>
- {#code_begin|test_err|access of union field 'float' while field 'int' is active#}
+ {#code_begin|test_err|test_wrong_union_access|access of union field 'float' while field 'int' is active#}
const Payload = union {
int: i64,
float: f64,
@@ -3963,7 +3962,7 @@ test "@tagName" {
{#header_open|Anonymous Union Literals#}
<p>{#link|Anonymous Struct Literals#} syntax can be used to initialize unions without specifying
the type:</p>
- {#code_begin|test|anon_union#}
+ {#code_begin|test|test_anonymous_union#}
const std = @import("std");
const expect = std.testing.expect;
@@ -3997,7 +3996,7 @@ fn makeNumber() Number {
This is typically used for type safety when interacting with C code that does not expose struct details.
Example:
</p>
- {#code_begin|test_err|expected type '*test.Derp', found '*test.Wat'#}
+ {#code_begin|test_err|test_opaque|expected type '*test_opaque.Derp', found '*test_opaque.Wat'#}
const Derp = opaque {};
const Wat = opaque {};
@@ -4016,7 +4015,7 @@ test "call foo" {
<p>
Blocks are used to limit the scope of variable declarations:
</p>
- {#code_begin|test_err|use of undeclared identifier 'x'#}
+ {#code_begin|test_err|test_blocks|use of undeclared identifier 'x'#}
test "access variable after block scope" {
{
var x: i32 = 1;
@@ -4048,7 +4047,7 @@ test "labeled break from labeled block expression" {
{#header_open|Shadowing#}
<p>{#link|Identifiers#} are never allowed to "hide" other identifiers by using the same name:</p>
- {#code_begin|test_err|local variable shadows declaration#}
+ {#code_begin|test_err|test_shadowing|local variable shadows declaration#}
const pi = 3.14;
test "inside test block" {
@@ -4079,7 +4078,7 @@ test "separate scopes" {
{#header_open|Empty Blocks#}
<p>An empty block is equivalent to {#syntax#}void{}{#endsyntax#}:</p>
- {#code_begin|test|empty_block#}
+ {#code_begin|test|test_empty_block#}
const std = @import("std");
const expect = std.testing.expect;
@@ -4095,7 +4094,7 @@ test {
{#header_close#}
{#header_open|switch#}
- {#code_begin|test|switch#}
+ {#code_begin|test|test_switch#}
const std = @import("std");
const builtin = @import("builtin");
const expect = std.testing.expect;
@@ -4212,7 +4211,7 @@ test "switch on tagged union" {
When a {#syntax#}switch{#endsyntax#} expression does not have an {#syntax#}else{#endsyntax#} clause,
it must exhaustively list all the possible values. Failure to do so is a compile error:
</p>
- {#code_begin|test_err|unhandled enumeration value#}
+ {#code_begin|test_err|test_unhandled_enumeration_value|unhandled enumeration value#}
const Color = enum {
auto,
off,
@@ -4390,7 +4389,7 @@ test "test" {
A while loop is used to repeatedly execute an expression until
some condition is no longer true.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while#}
const expect = @import("std").testing.expect;
test "while basic" {
@@ -4404,7 +4403,7 @@ test "while basic" {
<p>
Use {#syntax#}break{#endsyntax#} to exit a while loop early.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_break#}
const expect = @import("std").testing.expect;
test "while break" {
@@ -4420,7 +4419,7 @@ test "while break" {
<p>
Use {#syntax#}continue{#endsyntax#} to jump back to the beginning of the loop.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_continue#}
const expect = @import("std").testing.expect;
test "while continue" {
@@ -4438,7 +4437,7 @@ test "while continue" {
While loops support a continue expression which is executed when the loop
is continued. The {#syntax#}continue{#endsyntax#} keyword respects this expression.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_continue_expression#}
const expect = @import("std").testing.expect;
test "while loop continue expression" {
@@ -4467,7 +4466,7 @@ test "while loop continue expression, more complicated" {
When you {#syntax#}break{#endsyntax#} from a while loop, the {#syntax#}else{#endsyntax#} branch is not
evaluated.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_else#}
const expect = @import("std").testing.expect;
test "while else" {
@@ -4487,7 +4486,7 @@ fn rangeHasNumber(begin: usize, end: usize, number: usize) bool {
{#header_open|Labeled while#}
<p>When a {#syntax#}while{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
- {#code_begin|test|test_nested_break#}
+ {#code_begin|test|test_while_nested_break#}
test "nested break" {
outer: while (true) {
while (true) {
@@ -4520,7 +4519,7 @@ test "nested continue" {
The {#syntax#}else{#endsyntax#} branch is allowed on optional iteration. In this case, it will
be executed on the first null value encountered.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_null_capture#}
const expect = @import("std").testing.expect;
test "while null capture" {
@@ -4562,7 +4561,7 @@ fn eventuallyNullSequence() ?u32 {
When the {#syntax#}else |x|{#endsyntax#} syntax is present on a {#syntax#}while{#endsyntax#} expression,
the while condition must have an {#link|Error Union Type#}.
</p>
- {#code_begin|test|while#}
+ {#code_begin|test|test_while_error_capture#}
const expect = @import("std").testing.expect;
test "while error union capture" {
@@ -4627,7 +4626,7 @@ fn typeNameLength(comptime T: type) usize {
{#see_also|if|Optionals|Errors|comptime|unreachable#}
{#header_close#}
{#header_open|for#}
- {#code_begin|test|for#}
+ {#code_begin|test|test_for#}
const expect = @import("std").testing.expect;
test "for basics" {
@@ -4695,7 +4694,7 @@ test "for else" {
{#header_open|Labeled for#}
<p>When a {#syntax#}for{#endsyntax#} loop is labeled, it can be referenced from a {#syntax#}break{#endsyntax#}
or {#syntax#}continue{#endsyntax#} from within a nested loop:</p>
- {#code_begin|test|test_nested_break#}
+ {#code_begin|test|test_for_nested_break#}
const std = @import("std");
const expect = std.testing.expect;
@@ -4731,7 +4730,7 @@ test "nested continue" {
The capture value and iterator value of inlined for loops are
compile-time known.
</p>
- {#code_begin|test|test_inline_loop#}
+ {#code_begin|test|test_inline_for#}
const expect = @import("std").testing.expect;
test "inline for loop" {
@@ -4766,7 +4765,7 @@ fn typeNameLength(comptime T: type) usize {
{#see_also|while|comptime|Arrays|Slices#}
{#header_close#}
{#header_open|if#}
- {#code_begin|test|if#}
+ {#code_begin|test|test_if#}
// If expressions have three uses, corresponding to the three types:
// * bool
// * ?T
@@ -4927,7 +4926,7 @@ test "if error union with optional" {
{#see_also|Optionals|Errors#}
{#header_close#}
{#header_open|defer#}
- {#code_begin|test|defer#}
+ {#code_begin|test|test_defer#}
const std = @import("std");
const expect = std.testing.expect;
const print = std.debug.print;
@@ -4973,7 +4972,7 @@ test "defer unwinding" {
deferUnwindExample();
}
{#code_end#}
- {#code_begin|test_err|cannot return from defer expression#}
+ {#code_begin|test_err|test_invalid_defer|cannot return from defer expression#}
// Inside a defer expression the return statement is not allowed.
fn deferInvalidExample() !void {
defer {
@@ -4983,7 +4982,7 @@ fn deferInvalidExample() !void {
return error.DeferError;
}
{#code_end#}
- {#code_begin|test|errdefer#}
+ {#code_begin|test|test_errdefer#}
const std = @import("std");
const print = std.debug.print;
@@ -5052,7 +5051,7 @@ test "basic math" {
}
{#code_end#}
<p>In fact, this is how {#syntax#}std.debug.assert{#endsyntax#} is implemented:</p>
- {#code_begin|test_err#}
+ {#code_begin|test_err|test_assertion_failure#}
// This is how std.debug.assert is implemented
fn assert(ok: bool) void {
if (!ok) unreachable; // assertion failure
@@ -5065,7 +5064,7 @@ test "this will fail" {
{#code_end#}
{#header_close#}
{#header_open|At Compile-Time#}
- {#code_begin|test_err|unreachable code#}
+ {#code_begin|test_err|test_comptime_unreachable|unreachable code#}
const assert = @import("std").debug.assert;
test "type of unreachable" {
@@ -5107,7 +5106,7 @@ test "noreturn" {
}
{#code_end#}
<p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>
- {#code_begin|test|noreturn_from_exit#}
+ {#code_begin|test|test_noreturn_from_exit#}
{#target_windows#}
const std = @import("std");
const builtin = @import("builtin");
@@ -5130,7 +5129,7 @@ fn bar() anyerror!u32 {
{#header_close#}
{#header_open|Functions#}
- {#code_begin|test|functions#}
+ {#code_begin|test|test_functions#}
const std = @import("std");
const builtin = @import("builtin");
const native_arch = builtin.cpu.arch;
@@ -5206,7 +5205,7 @@ test "function" {
as parameters, Zig may choose to copy and pass by value, or pass by reference, whichever way
Zig decides will be faster. This is made possible, in part, by the fact that parameters are immutable.
</p>
- {#code_begin|test|pass_by_reference_or_value#}
+ {#code_begin|test|test_pass_by_reference_or_value#}
const Point = struct {
x: i32,
y: i32,
@@ -5283,7 +5282,7 @@ test "fn reflection" {
<p>
You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
</p>
- {#code_begin|test|coercing_subset_to_superset#}
+ {#code_begin|test|test_coerce_error_subset_to_superset#}
const std = @import("std");
const FileOpenError = error {
@@ -5308,7 +5307,7 @@ fn foo(err: AllocationError) FileOpenError {
<p>
But you cannot {#link|coerce|Type Coercion#} an error from a superset to a subset:
</p>
- {#code_begin|test_err|not a member of destination error set#}
+ {#code_begin|test_err|test_coerce_error_superset_to_subset|not a member of destination error set#}
const FileOpenError = error {
AccessDenied,
OutOfMemory,
@@ -5330,11 +5329,11 @@ fn foo(err: FileOpenError) AllocationError {
<p>
There is a shortcut for declaring an error set with only 1 value, and then getting that value:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|single_value_error_set_shortcut#}
const err = error.FileNotFound;
{#code_end#}
<p>This is equivalent to:</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|single_value_error_set#}
const err = (error {FileNotFound}).FileNotFound;
{#code_end#}
<p>
@@ -5431,7 +5430,7 @@ test "parse u64" {
</ul>
{#header_open|catch#}
<p>If you want to provide a default value, you can use the {#syntax#}catch{#endsyntax#} binary operator:</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|catch#}
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
fn doAThing(str: []u8) void {
@@ -5448,7 +5447,7 @@ fn doAThing(str: []u8) void {
{#header_open|try#}
<p>Let's say you wanted to return the error if you got one, otherwise continue with the
function logic:</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|catch_err_return#}
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
fn doAThing(str: []u8) !void {
@@ -5459,7 +5458,7 @@ fn doAThing(str: []u8) !void {
<p>
There is a shortcut for this. The {#syntax#}try{#endsyntax#} expression:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|try#}
const parseU64 = @import("error_union_parsing_u64.zig").parseU64;
fn doAThing(str: []u8) !void {
@@ -5543,7 +5542,7 @@ fn createFoo(param: i32) !Foo {
It should be noted that {#syntax#}errdefer{#endsyntax#} statements only last until the end of the block
they are written in, and therefore are not run if an error is returned outside of that block:
</p>
- {#code_begin|test_err|1 tests leaked memory#}
+ {#code_begin|test_err|test_errdefer_slip_ups|1 tests leaked memory#}
const std = @import("std");
const Allocator = std.mem.Allocator;
@@ -5635,7 +5634,7 @@ test "createFoo" {
The fact that errdefers only last for the block they are declared in is
especially important when using loops:
</p>
- {#code_begin|test_err|3 errors were logged#}
+ {#code_begin|test_err|test_errdefer_loop_leak|3 errors were logged#}
const std = @import("std");
const Allocator = std.mem.Allocator;
@@ -5799,7 +5798,7 @@ test "merge error sets" {
Because many functions in Zig return a possible error, Zig supports inferring the error set.
To infer the error set for a function, prepend the {#syntax#}!{#endsyntax#} operator to the function’s return type, like {#syntax#}!T{#endsyntax#}:
</p>
-{#code_begin|test|inferred_error_sets#}
+ {#code_begin|test|test_inferred_error_sets#}
// With an inferred error set
pub fn add_inferred(comptime T: type, a: T, b: T) !T {
const ov = @addWithOverflow(a, b);
@@ -5825,7 +5824,7 @@ test "inferred error set" {
error.Overflow => {}, // ok
}
}
-{#code_end#}
+ {#code_end#}
<p>
When a function has an inferred error set, that function becomes generic and thus it becomes
trickier to do certain things with it, such as obtain a function pointer, or have an error
@@ -5845,7 +5844,7 @@ test "inferred error set" {
<p>
Error Return Traces show all the points in the code that an error was returned to the calling function. This makes it practical to use {#link|try#} everywhere and then still be able to know what happened if an error ends up bubbling all the way out of your application.
</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|error_return_trace#}
pub fn main() !void {
try foo(12);
}
@@ -5894,7 +5893,7 @@ fn bang2() !void {
but the original error that started this whole thing was {#syntax#}FileNotFound{#endsyntax#}. In the {#syntax#}bar{#endsyntax#} function, the code handles the original error code,
and then returns another one, from the switch statement. Error Return Traces make this clear, whereas a stack trace would look like this:
</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|stack_trace#}
pub fn main() void {
foo(12);
}
@@ -6016,7 +6015,7 @@ fn __zig_return_error(stack_trace: *StackTrace) void {
The question mark symbolizes the optional type. You can convert a type to an optional
type by putting a question mark in front of it, like this:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|optional_integer#}
// normal integer
const normal_int: i32 = 1234;
@@ -6137,7 +6136,7 @@ test "optional type" {
Just like {#link|undefined#}, {#syntax#}null{#endsyntax#} has its own type, and the only way to use it is to
cast it to a different type:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|null#}
const optional_value: ?i32 = null;
{#code_end#}
{#header_close#}
@@ -6176,7 +6175,7 @@ test "optional pointers" {
<p>
Type coercion occurs when one type is expected, but different type is provided:
</p>
- {#code_begin|test|type_coercion#}
+ {#code_begin|test|test_type_coercion#}
test "type coercion - variable declaration" {
var a: u8 = 1;
var b: u16 = a;
@@ -6216,7 +6215,7 @@ test "type coercion - @as builtin" {
<p>
These casts are no-ops at runtime since the value representation does not change.
</p>
- {#code_begin|test|no_op_casts#}
+ {#code_begin|test|test_no_op_casts#}
test "type coercion - const qualification" {
var a: i32 = 1;
var b: *i32 = &a;
@@ -6228,7 +6227,7 @@ fn foo(_: *const i32) void {}
<p>
In addition, pointers coerce to const optional pointers:
</p>
- {#code_begin|test|pointer_coerce_const_optional#}
+ {#code_begin|test|test_pointer_coerce_const_optional#}
const std = @import("std");
const expect = std.testing.expect;
const mem = std.mem;
@@ -6285,7 +6284,7 @@ test "float widening" {
<li>Cast {#syntax#}54.0{#endsyntax#} to {#syntax#}comptime_int{#endsyntax#} resulting in {#syntax#}@as(comptime_int, 10){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10){#endsyntax#}</li>
<li>Cast {#syntax#}5{#endsyntax#} to {#syntax#}comptime_float{#endsyntax#} resulting in {#syntax#}@as(comptime_float, 10.8){#endsyntax#}, which is casted to {#syntax#}@as(f32, 10.8){#endsyntax#}</li>
</ul>
- {#code_begin|test_err#}
+ {#code_begin|test_err|test_ambiguous_coercion#}
// Compile time coercion of float to int
test "implicit cast to comptime_int" {
var f: f32 = 54.0 / 5;
@@ -6294,7 +6293,7 @@ test "implicit cast to comptime_int" {
{#code_end#}
{#header_close#}
{#header_open|Type Coercion: Slices, Arrays and Pointers#}
- {#code_begin|test|coerce__slices_arrays_and_ptrs#}
+ {#code_begin|test|test_coerce_slices_arrays_and_pointers#}
const std = @import("std");
const expect = std.testing.expect;
@@ -6522,7 +6521,7 @@ test "coercion from homogenous tuple to array" {
This kind of type resolution chooses a type that all peer types can coerce into. Here are
some examples:
</p>
- {#code_begin|test|peer_type_resolution#}
+ {#code_begin|test|test_peer_type_resolution#}
const std = @import("std");
const expect = std.testing.expect;
const mem = std.mem;
@@ -6634,7 +6633,7 @@ test "peer type resolution: *const T and ?*T" {
require 0 bits to represent. Code that makes use of these types is
not included in the final generated code:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|zero_bit_types#}
export fn entry() void {
var x: void = {};
var y: void = {};
@@ -6657,7 +6656,7 @@ export fn entry() void {
{#syntax#}Map(Key, Value){#endsyntax#}, one can pass {#syntax#}void{#endsyntax#} for the {#syntax#}Value{#endsyntax#}
type to make it into a {#syntax#}Set{#endsyntax#}:
</p>
- {#code_begin|test|void_in_hashmap#}
+ {#code_begin|test|test_void_in_hashmap#}
const std = @import("std");
const expect = std.testing.expect;
@@ -6687,7 +6686,7 @@ test "turn HashMap into a set with void" {
<p>
Expressions of type {#syntax#}void{#endsyntax#} are the only ones whose value can be ignored. For example:
</p>
- {#code_begin|test_err|ignored#}
+ {#code_begin|test_err|test_expression_ignored|ignored#}
test "ignoring expression value" {
foo();
}
@@ -6697,7 +6696,7 @@ fn foo() i32 {
}
{#code_end#}
<p>However, if the expression has type {#syntax#}void{#endsyntax#}, there will be no error. Function return values can also be explicitly ignored by assigning them to {#syntax#}_{#endsyntax#}. </p>
- {#code_begin|test|void_ignored#}
+ {#code_begin|test|test_void_ignored#}
test "void is ignored" {
returnsVoid();
}
@@ -6727,7 +6726,7 @@ fn foo() i32 {
declarations of the operand, which must be a {#link|struct#}, {#link|union#}, {#link|enum#},
or {#link|opaque#}, into the namespace:
</p>
- {#code_begin|test|usingnamespace#}
+ {#code_begin|test|test_usingnamespace#}
test "using std namespace" {
const S = struct {
usingnamespace @import("std");
@@ -6769,7 +6768,7 @@ pub usingnamespace @cImport({
<p>
Compile-time parameters is how Zig implements generics. It is compile-time duck typing.
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|compile-time_duck_typing#}
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
@@ -6795,7 +6794,7 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
<p>
For example, if we were to introduce another function to the above snippet:
</p>
- {#code_begin|test_err|unable to resolve comptime value#}
+ {#code_begin|test_err|test_unresolved_comptime_value|unable to resolve comptime value#}
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
@@ -6821,7 +6820,7 @@ fn foo(condition: bool) void {
<p>
For example:
</p>
- {#code_begin|test_err|operator > not allowed for type 'bool'#}
+ {#code_begin|test_err|test_comptime_mismatched_type|operator > not allowed for type 'bool'#}
fn max(comptime T: type, a: T, b: T) T {
return if (a > b) a else b;
}
@@ -6834,7 +6833,7 @@ test "try to compare bools" {
value is known at compile-time. This means that we actually could make this work for the bool type
if we wanted to:
</p>
- {#code_begin|test|comptime_max_with_bool#}
+ {#code_begin|test|test_comptime_max_with_bool#}
fn max(comptime T: type, a: T, b: T) T {
if (T == bool) {
return a or b;
@@ -6857,7 +6856,7 @@ test "try to compare bools" {
This means that the actual function generated for {#syntax#}max{#endsyntax#} in this situation looks like
this:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|compiler_generated_function#}
fn max(a: bool, b: bool) bool {
return a or b;
}
@@ -6884,7 +6883,7 @@ fn max(a: bool, b: bool) bool {
<p>
For example:
</p>
- {#code_begin|test|comptime_vars#}
+ {#code_begin|test|test_comptime_evaluation#}
const expect = @import("std").testing.expect;
const CmdFn = struct {
@@ -6966,7 +6965,7 @@ fn performFn(start_value: i32) i32 {
use a {#syntax#}comptime{#endsyntax#} expression to guarantee that the expression will be evaluated at compile-time.
If this cannot be accomplished, the compiler will emit an error. For example:
</p>
- {#code_begin|test_err|comptime call of extern function#}
+ {#code_begin|test_err|test_comptime_call_extern_function|comptime call of extern function#}
extern fn exit() noreturn;
test "foo" {
@@ -6997,7 +6996,7 @@ test "foo" {
<p>
Let's look at an example:
</p>
- {#code_begin|test|fibonacci_recursion#}
+ {#code_begin|test|test_fibonacci_recursion#}
const expect = @import("std").testing.expect;
fn fibonacci(index: u32) u32 {
@@ -7018,7 +7017,7 @@ test "fibonacci" {
<p>
Imagine if we had forgotten the base case of the recursive function and tried to run the tests:
</p>
- {#code_begin|test_err|overflow of integer type#}
+ {#code_begin|test_err|test_fibonacci_comptime_overflow|overflow of integer type#}
const expect = @import("std").testing.expect;
fn fibonacci(index: u32) u32 {
@@ -7041,7 +7040,7 @@ test "fibonacci" {
undefined behavior, which is always a compile error if the compiler knows it happened.
But what would have happened if we used a signed integer?
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|fibonacci_comptime_infinite_recursion#}
const assert = @import("std").debug.assert;
fn fibonacci(index: i32) i32 {
@@ -7073,7 +7072,7 @@ test "fibonacci" {
What if we fix the base case, but put the wrong value in the
{#syntax#}expect{#endsyntax#} line?
</p>
- {#code_begin|test_err|reached unreachable#}
+ {#code_begin|test_err|test_fibonacci_comptime_unreachable|reached unreachable#}
const assert = @import("std").debug.assert;
fn fibonacci(index: i32) i32 {
@@ -7093,7 +7092,7 @@ test "fibonacci" {
{#syntax#}comptime{#endsyntax#} expressions. This means that we can use functions to
initialize complex static data. For example:
</p>
- {#code_begin|test|N_primes#}
+ {#code_begin|test|test_container-level_comptime_expressions#}
const first_25_primes = firstNPrimes(25);
const sum_of_first_25_primes = sum(&first_25_primes);
@@ -7152,7 +7151,7 @@ test "variable values" {
<p>
Here is an example of a generic {#syntax#}List{#endsyntax#} data structure.
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|generic_data_structure#}
fn List(comptime T: type) type {
return struct {
items: []T,
@@ -7177,7 +7176,7 @@ var list = List(i32){
<p>
To explicitly give a type a name, we assign it to a constant.
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|anonymous_struct_name#}
const Node = struct {
next: ?*Node,
name: []const u8,
@@ -7360,7 +7359,7 @@ pub fn print(self: *Writer, arg0: []const u8, arg1: i32) !void {
<p>
And now, what happens if we give too many arguments to {#syntax#}print{#endsyntax#}?
</p>
- {#code_begin|test_err|unused argument in 'here is a string: '{s}' here is a number: {}#}
+ {#code_begin|test_err|test_print_too_many_args|unused argument in 'here is a string: '{s}' here is a number: {}#}
const print = @import("std").debug.print;
const a_number: i32 = 1234;
@@ -7381,7 +7380,7 @@ test "print too many arguments" {
Zig doesn't care whether the format argument is a string literal,
only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}:
</p>
- {#code_begin|exe|print#}
+ {#code_begin|exe|print_comptime-known_format#}
const print = @import("std").debug.print;
const a_number: i32 = 1234;
@@ -7410,7 +7409,7 @@ pub fn main() void {
can use inline assembly. Here is an example of implementing Hello, World on x86_64 Linux
using inline assembly:
</p>
- {#code_begin|exe#}
+ {#code_begin|exe|inline_assembly#}
{#target_linux_x86_64#}
pub fn main() noreturn {
const msg = "hello world\n";
@@ -7572,7 +7571,7 @@ volatile (
verbatim into one long string and assembled together. There are no template substitution rules regarding
<code>%</code> as there are in inline assembly expressions.
</p>
- {#code_begin|test|global-asm#}
+ {#code_begin|test|test_global_assembly#}
{#target_linux_x86_64#}
const std = @import("std");
const expect = std.testing.expect;
@@ -7845,7 +7844,7 @@ comptime {
<p>
Calls a function, in the same way that invoking an expression with parentheses does:
</p>
- {#code_begin|test|call#}
+ {#code_begin|test|test_call_builtin#}
const expect = @import("std").testing.expect;
test "noinline function call" {
@@ -7979,7 +7978,7 @@ pub const CallModifier = enum {
This function performs a strong atomic compare exchange operation. It's the equivalent of this code,
except atomic:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|not_atomic_cmpxchgStrong#}
fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_value: T) ?T {
const old_value = ptr.*;
if (old_value == expected_value) {
@@ -8060,7 +8059,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
This function can be used to do "printf debugging" on
compile-time executing code.
</p>
- {#code_begin|test_err|found compile log statement#}
+ {#code_begin|test_err|test_compileLog_builtin|found compile log statement#}
const print = @import("std").debug.print;
const num1 = blk: {
@@ -8081,7 +8080,7 @@ test "main" {
not encountered by analysis, the
program compiles successfully and the generated executable prints:
</p>
- {#code_begin|test|without_compileLog#}
+ {#code_begin|test|test_without_compileLog_builtin#}
const print = @import("std").debug.print;
const num1 = blk: {
@@ -8296,7 +8295,7 @@ test "main" {
{#syntax#}options.linkage{#endsyntax#} is {#syntax#}Strong{#endsyntax#}, this is equivalent to
the {#syntax#}export{#endsyntax#} keyword used on a function:
</p>
- {#code_begin|obj#}
+ {#code_begin|obj|export_builtin#}
comptime {
@export(internalName, .{ .name = "foo", .linkage = .Strong });
}
@@ -8304,12 +8303,12 @@ comptime {
fn internalName() callconv(.C) void {}
{#code_end#}
<p>This is equivalent to:</p>
- {#code_begin|obj#}
+ {#code_begin|obj|export_builtin_equivalent_code#}
export fn foo() void {}
{#code_end#}
<p>Note that even when using {#syntax#}export{#endsyntax#}, the {#syntax#}@"foo"{#endsyntax#} syntax for
{#link|identifiers|Identifiers#} can be used to choose any string for the symbol name:</p>
- {#code_begin|obj#}
+ {#code_begin|obj|export_any_symbol_name#}
export fn @"A function name that is a complete sentence."() void {}
{#code_end#}
<p>
@@ -8342,7 +8341,7 @@ export fn @"A function name that is a complete sentence."() void {}
<pre>{#syntax#}@field(lhs: anytype, comptime field_name: []const u8) (field){#endsyntax#}</pre>
<p>Performs field access by a compile-time string. Works on both fields and declarations.
</p>
- {#code_begin|test|field_decl_access_by_string#}
+ {#code_begin|test|test_field_builtin#}
const std = @import("std");
const Point = struct {
@@ -8424,7 +8423,7 @@ test "decl access by string" {
Returns whether or not a {#link|container|Containers#} has a declaration
matching {#syntax#}name{#endsyntax#}.
</p>
- {#code_begin|test|hasDecl#}
+ {#code_begin|test|test_hasDecl_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -8504,7 +8503,7 @@ test "@hasDecl" {
Attempting to convert a number which is out of range of the destination type results in
safety-protected {#link|Undefined Behavior#}.
</p>
- {#code_begin|test_err|cast truncated bits#}
+ {#code_begin|test_err|test_intCast_builtin|cast truncated bits#}
test "integer cast panic" {
var a: u16 = 0xabcd;
var b: u8 = @intCast(u8, a);
@@ -8654,7 +8653,7 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
designers targeting Wasm. So unless you are writing a new allocator from scratch, you should use
something like {#syntax#}@import("std").heap.WasmPageAllocator{#endsyntax#}.
</p>
- {#code_begin|test|wasmMemoryGrow#}
+ {#code_begin|test|test_wasmMemoryGrow_builtin#}
const std = @import("std");
const native_arch = @import("builtin").target.cpu.arch;
const expect = std.testing.expect;
@@ -8855,7 +8854,7 @@ pub const PrefetchOptions = struct {
<p>
Example:
</p>
- {#code_begin|test_err|evaluation exceeded 1000 backwards branches#}
+ {#code_begin|test_err|test_without_setEvalBranchQuota_builtin|evaluation exceeded 1000 backwards branches#}
test "foo" {
comptime {
var i = 0;
@@ -8864,7 +8863,7 @@ test "foo" {
}
{#code_end#}
<p>Now we use {#syntax#}@setEvalBranchQuota{#endsyntax#}:</p>
- {#code_begin|test|setEvalBranchQuota#}
+ {#code_begin|test|test_setEvalBranchQuota_builtin#}
test "foo" {
comptime {
@setEvalBranchQuota(1001);
@@ -8882,7 +8881,7 @@ test "foo" {
<p>
Sets the floating point mode of the current scope. Possible values are:
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|FloatMode#}
pub const FloatMode = enum {
Strict,
Optimized,
@@ -8917,7 +8916,7 @@ pub const FloatMode = enum {
<p>
Sets whether runtime safety checks are enabled for the scope that contains the function call.
</p>
- {#code_begin|test_safety|integer overflow#}
+ {#code_begin|test_safety|test_setRuntimeSafety_builtin|integer overflow#}
{#code_release_fast#}
test "@setRuntimeSafety" {
// The builtin applies to the scope that it is called in. So here, integer overflow
@@ -9020,7 +9019,7 @@ test "@setRuntimeSafety" {
{#link|pointer|Pointers#}, or {#syntax#}bool{#endsyntax#}. The mask may be any vector length, and its
length determines the result length.
</p>
- {#code_begin|test|vector_shuffle#}
+ {#code_begin|test|test_shuffle_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9068,7 +9067,7 @@ test "vector @shuffle" {
Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value
{#syntax#}scalar{#endsyntax#}:
</p>
- {#code_begin|test|vector_splat#}
+ {#code_begin|test|test_splat_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9111,7 +9110,7 @@ test "vector @splat" {
types the operation associativity is preserved, unless the float mode is
set to {#syntax#}Optimized{#endsyntax#}.
</p>
- {#code_begin|test|vector_reduce#}
+ {#code_begin|test|test_reduce_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9133,7 +9132,7 @@ test "vector @reduce" {
<p>
Returns a {#syntax#}SourceLocation{#endsyntax#} struct representing the function's name and location in the source code. This must be called in a function.
</p>
- {#code_begin|test|source_location#}
+ {#code_begin|test|test_src_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9147,7 +9146,7 @@ fn doTheTest() !void {
try expect(src.line == 9);
try expect(src.column == 17);
try expect(std.mem.endsWith(u8, src.fn_name, "doTheTest"));
- try expect(std.mem.endsWith(u8, src.file, "source_location.zig"));
+ try expect(std.mem.endsWith(u8, src.file, "test_src_builtin.zig"));
}
{#code_end#}
{#header_close#}
@@ -9329,7 +9328,7 @@ fn doTheTest() !void {
Returns the innermost struct, enum, or union that this function call is inside.
This can be useful for an anonymous struct that needs to refer to itself:
</p>
- {#code_begin|test|this_innermost#}
+ {#code_begin|test|test_this_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9370,7 +9369,7 @@ fn List(comptime T: type) type {
<p>
Calling {#syntax#}@truncate{#endsyntax#} on a number out of range of the destination type is well defined and working code:
</p>
- {#code_begin|test|truncate#}
+ {#code_begin|test|test_truncate_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9458,7 +9457,7 @@ test "integer truncation" {
<p>
The expressions are evaluated, however they are guaranteed to have no <em>runtime</em> side-effects:
</p>
- {#code_begin|test|no_runtime_side_effects#}
+ {#code_begin|test|test_TypeOf_builtin#}
const std = @import("std");
const expect = std.testing.expect;
@@ -9592,14 +9591,14 @@ pub fn build(b: *Builder) void {
<p>
When a safety check fails, Zig crashes with a stack trace, like this:
</p>
- {#code_begin|test_err|reached unreachable code#}
+ {#code_begin|test_err|test_undefined_behavior|reached unreachable code#}
test "safety check" {
unreachable;
}
{#code_end#}
{#header_open|Reaching Unreachable Code#}
<p>At compile-time:</p>
- {#code_begin|test_err|reached unreachable code#}
+ {#code_begin|test_err|test_comptime_reaching_unreachable|reached unreachable code#}
comptime {
assert(false);
}
@@ -9608,7 +9607,7 @@ fn assert(ok: bool) void {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_reaching_unreachable#}
const std = @import("std");
pub fn main() void {
@@ -9618,7 +9617,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Index out of Bounds#}
<p>At compile-time:</p>
- {#code_begin|test_err|index 5 outside array of length 5#}
+ {#code_begin|test_err|test_comptime_index_out_of_bounds|index 5 outside array of length 5#}
comptime {
const array: [5]u8 = "hello".*;
const garbage = array[5];
@@ -9626,7 +9625,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_index_out_of_bounds#}
pub fn main() void {
var x = foo("hello");
_ = x;
@@ -9639,7 +9638,7 @@ fn foo(x: []const u8) u8 {
{#header_close#}
{#header_open|Cast Negative Number to Unsigned Integer#}
<p>At compile-time:</p>
- {#code_begin|test_err|type 'u32' cannot represent integer value '-1'#}
+ {#code_begin|test_err|test_comptime_invalid_cast|type 'u32' cannot represent integer value '-1'#}
comptime {
var value: i32 = -1;
const unsigned = @intCast(u32, value);
@@ -9647,7 +9646,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_cast#}
const std = @import("std");
pub fn main() void {
@@ -9662,7 +9661,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Cast Truncates Data#}
<p>At compile-time:</p>
- {#code_begin|test_err|type 'u8' cannot represent integer value '300'#}
+ {#code_begin|test_err|test_comptime_invalid_cast_truncate|type 'u8' cannot represent integer value '300'#}
comptime {
const spartan_count: u16 = 300;
const byte = @intCast(u8, spartan_count);
@@ -9670,7 +9669,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_cast_truncate#}
const std = @import("std");
pub fn main() void {
@@ -9697,14 +9696,14 @@ pub fn main() void {
<li>{#link|@divExact#} (division)</li>
</ul>
<p>Example with addition at compile-time:</p>
- {#code_begin|test_err|overflow of integer type 'u8' with value '256'#}
+ {#code_begin|test_err|test_comptime_overflow|overflow of integer type 'u8' with value '256'#}
comptime {
var byte: u8 = 255;
byte += 1;
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_overflow#}
const std = @import("std");
pub fn main() void {
@@ -9726,7 +9725,7 @@ pub fn main() void {
<li>{#syntax#}@import("std").math.shl{#endsyntax#}</li>
</ul>
<p>Example of catching an overflow for addition:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|math_add#}
const math = @import("std").math;
const print = @import("std").debug.print;
pub fn main() !void {
@@ -9755,7 +9754,7 @@ pub fn main() !void {
<p>
Example of {#link|@addWithOverflow#}:
</p>
- {#code_begin|exe#}
+ {#code_begin|exe|addWithOverflow_builtin#}
const print = @import("std").debug.print;
pub fn main() void {
var byte: u8 = 255;
@@ -9779,7 +9778,7 @@ pub fn main() void {
<li>{#syntax#}-%{#endsyntax#} (wraparound negation)</li>
<li>{#syntax#}*%{#endsyntax#} (wraparound multiplication)</li>
</ul>
- {#code_begin|test|wraparound_semantics#}
+ {#code_begin|test|test_wraparound_semantics#}
const std = @import("std");
const expect = std.testing.expect;
const minInt = std.math.minInt;
@@ -9797,14 +9796,14 @@ test "wraparound addition and subtraction" {
{#header_close#}
{#header_open|Exact Left Shift Overflow#}
<p>At compile-time:</p>
- {#code_begin|test_err|operation caused overflow#}
+ {#code_begin|test_err|test_comptime_shlExact_overwlow|operation caused overflow#}
comptime {
const x = @shlExact(@as(u8, 0b01010101), 2);
_ = x;
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_shlExact_overflow#}
const std = @import("std");
pub fn main() void {
@@ -9816,14 +9815,14 @@ pub fn main() void {
{#header_close#}
{#header_open|Exact Right Shift Overflow#}
<p>At compile-time:</p>
- {#code_begin|test_err|exact shift shifted out 1 bits#}
+ {#code_begin|test_err|test_comptime_shrExact_overflow|exact shift shifted out 1 bits#}
comptime {
const x = @shrExact(@as(u8, 0b10101010), 2);
_ = x;
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_shrExact_overflow#}
const std = @import("std");
pub fn main() void {
@@ -9835,7 +9834,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Division by Zero#}
<p>At compile-time:</p>
- {#code_begin|test_err|division by zero#}
+ {#code_begin|test_err|test_comptime_division_by_zero|division by zero#}
comptime {
const a: i32 = 1;
const b: i32 = 0;
@@ -9844,7 +9843,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_division_by_zero#}
const std = @import("std");
pub fn main() void {
@@ -9857,7 +9856,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Remainder Division by Zero#}
<p>At compile-time:</p>
- {#code_begin|test_err|division by zero#}
+ {#code_begin|test_err|test_comptime_remainder_division_by_zero|division by zero#}
comptime {
const a: i32 = 10;
const b: i32 = 0;
@@ -9866,7 +9865,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_remainder_division_by_zero#}
const std = @import("std");
pub fn main() void {
@@ -9879,7 +9878,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Exact Division Remainder#}
<p>At compile-time:</p>
- {#code_begin|test_err|exact division produced remainder#}
+ {#code_begin|test_err|test_comptime_divExact_remainder|exact division produced remainder#}
comptime {
const a: u32 = 10;
const b: u32 = 3;
@@ -9888,7 +9887,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_divExact_remainder#}
const std = @import("std");
pub fn main() void {
@@ -9901,7 +9900,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Attempt to Unwrap Null#}
<p>At compile-time:</p>
- {#code_begin|test_err|unable to unwrap null#}
+ {#code_begin|test_err|test_comptime_unwrap_null|unable to unwrap null#}
comptime {
const optional_number: ?i32 = null;
const number = optional_number.?;
@@ -9909,7 +9908,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_unwrap_null#}
const std = @import("std");
pub fn main() void {
@@ -9920,7 +9919,7 @@ pub fn main() void {
{#code_end#}
<p>One way to avoid this crash is to test for null instead of assuming non-null, with
the {#syntax#}if{#endsyntax#} expression:</p>
- {#code_begin|exe|test#}
+ {#code_begin|exe|testing_null_with_if#}
const print = @import("std").debug.print;
pub fn main() void {
const optional_number: ?i32 = null;
@@ -9936,7 +9935,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Attempt to Unwrap Error#}
<p>At compile-time:</p>
- {#code_begin|test_err|caught unexpected error 'UnableToReturnNumber'#}
+ {#code_begin|test_err|test_comptime_unwrap_error|caught unexpected error 'UnableToReturnNumber'#}
comptime {
const number = getNumberOrFail() catch unreachable;
_ = number;
@@ -9947,7 +9946,7 @@ fn getNumberOrFail() !i32 {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_unwrap_error#}
const std = @import("std");
pub fn main() void {
@@ -9961,7 +9960,7 @@ fn getNumberOrFail() !i32 {
{#code_end#}
<p>One way to avoid this crash is to test for an error instead of assuming a successful result, with
the {#syntax#}if{#endsyntax#} expression:</p>
- {#code_begin|exe#}
+ {#code_begin|exe|testing_error_with_if#}
const print = @import("std").debug.print;
pub fn main() void {
@@ -9982,7 +9981,7 @@ fn getNumberOrFail() !i32 {
{#header_close#}
{#header_open|Invalid Error Code#}
<p>At compile-time:</p>
- {#code_begin|test_err|integer value '11' represents no error#}
+ {#code_begin|test_err|test_comptime_invalid_error_code|integer value '11' represents no error#}
comptime {
const err = error.AnError;
const number = @errorToInt(err) + 10;
@@ -9991,7 +9990,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_error_code#}
const std = @import("std");
pub fn main() void {
@@ -10004,7 +10003,7 @@ pub fn main() void {
{#header_close#}
{#header_open|Invalid Enum Cast#}
<p>At compile-time:</p>
- {#code_begin|test_err|enum 'test.Foo' has no tag with value '3'#}
+ {#code_begin|test_err|test_comptime_invalid_enum_cast|enum 'test_comptime_invalid_enum_cast.Foo' has no tag with value '3'#}
const Foo = enum {
a,
b,
@@ -10017,7 +10016,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_enum_cast#}
const std = @import("std");
const Foo = enum {
@@ -10036,7 +10035,7 @@ pub fn main() void {
{#header_open|Invalid Error Set Cast#}
<p>At compile-time:</p>
- {#code_begin|test_err|'error.B' not a member of error set 'error{A,C}'#}
+ {#code_begin|test_err|test_comptime_invalid_error_set_cast|'error.B' not a member of error set 'error{A,C}'#}
const Set1 = error{
A,
B,
@@ -10050,7 +10049,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_error_set_cast#}
const std = @import("std");
const Set1 = error{
@@ -10073,7 +10072,7 @@ fn foo(set1: Set1) void {
{#header_open|Incorrect Pointer Alignment#}
<p>At compile-time:</p>
- {#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#}
+ {#code_begin|test_err|test_comptime_incorrect_pointer_alignment|pointer address 0x1 is not aligned to 4 bytes#}
comptime {
const ptr = @intToPtr(*align(1) i32, 0x1);
const aligned = @alignCast(4, ptr);
@@ -10081,7 +10080,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_incorrect_pointer_alignment#}
const mem = @import("std").mem;
pub fn main() !void {
var array align(4) = [_]u32{ 0x11111111, 0x11111111 };
@@ -10097,7 +10096,7 @@ fn foo(bytes: []u8) u32 {
{#header_close#}
{#header_open|Wrong Union Field Access#}
<p>At compile-time:</p>
- {#code_begin|test_err|access of union field 'float' while field 'int' is active#}
+ {#code_begin|test_err|test_comptime_wrong_union_field_access|access of union field 'float' while field 'int' is active#}
comptime {
var f = Foo{ .int = 42 };
f.float = 12.34;
@@ -10109,7 +10108,7 @@ const Foo = union {
};
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_wrong_union_field_access#}
const std = @import("std");
const Foo = union {
@@ -10133,7 +10132,7 @@ fn bar(f: *Foo) void {
<p>
To change the active field of a union, assign the entire union, like this:
</p>
- {#code_begin|exe#}
+ {#code_begin|exe|change_active_union_field#}
const std = @import("std");
const Foo = union {
@@ -10155,7 +10154,7 @@ fn bar(f: *Foo) void {
To change the active field of a union when a meaningful value for the field is not known,
use {#link|undefined#}, like this:
</p>
- {#code_begin|exe#}
+ {#code_begin|exe|undefined_active_union_field#}
const std = @import("std");
const Foo = union {
@@ -10188,7 +10187,7 @@ fn bar(f: *Foo) void {
allow address zero, but normal {#link|Pointers#} do not.
</p>
<p>At compile-time:</p>
- {#code_begin|test_err|null pointer casted to type#}
+ {#code_begin|test_err|test_comptime_invalid_null_pointer_cast|null pointer casted to type#}
comptime {
const opt_ptr: ?*i32 = null;
const ptr = @ptrCast(*i32, opt_ptr);
@@ -10196,7 +10195,7 @@ comptime {
}
{#code_end#}
<p>At runtime:</p>
- {#code_begin|exe_err#}
+ {#code_begin|exe_err|runtime_invalid_null_pointer_cast#}
pub fn main() void {
var opt_ptr: ?*i32 = null;
var ptr = @ptrCast(*i32, opt_ptr);
@@ -10224,7 +10223,7 @@ pub fn main() void {
{#syntax#}std.ArrayList{#endsyntax#} accept an {#syntax#}Allocator{#endsyntax#} parameter in
their initialization functions:
</p>
- {#code_begin|test|allocator#}
+ {#code_begin|test|test_allocator#}
const std = @import("std");
const Allocator = std.mem.Allocator;
const expect = std.testing.expect;
@@ -10278,7 +10277,7 @@ fn concat(allocator: Allocator, a: []const u8, b: []const u8) ![]u8 {
cyclical pattern (such as a video game main loop, or a web server request handler),
such that it would make sense to free everything at once at the end?
In this case, it is recommended to follow this pattern:
- {#code_begin|exe|cli_allocation#}
+ {#code_begin|exe|cli_allocation#}
const std = @import("std");
pub fn main() !void {
@@ -10290,7 +10289,7 @@ pub fn main() !void {
const ptr = try allocator.create(i32);
std.debug.print("ptr={*}\n", .{ptr});
}
- {#code_end#}
+ {#code_end#}
When using this kind of allocator, there is no need to free anything manually. Everything
gets freed at once with the call to {#syntax#}arena.deinit(){#endsyntax#}.
</li>
@@ -10328,7 +10327,7 @@ pub fn main() !void {
<p>String literals such as {#syntax#}"foo"{#endsyntax#} are in the global constant data section.
This is why it is an error to pass a string literal to a mutable slice, like this:
</p>
- {#code_begin|test_err|expected type '[]u8', found '*const [5:0]u8'#}
+ {#code_begin|test_err|test_string_literal_to_slice|expected type '[]u8', found '*const [5:0]u8'#}
fn foo(s: []u8) void {
_ = s;
}
@@ -10338,7 +10337,7 @@ test "string literal to mutable slice" {
}
{#code_end#}
<p>However if you make the slice constant, then it works:</p>
- {#code_begin|test|strlit#}
+ {#code_begin|test|test_string_literal_to_const_slice#}
fn foo(s: []const u8) void {
_ = s;
}
@@ -10474,7 +10473,7 @@ test "string literal to constant slice" {
which the compiler makes available to every Zig source file. It contains
compile-time constants such as the current target, endianness, and release mode.
</p>
- {#code_begin|syntax#}
+ {#code_begin|syntax|compile_variables#}
const builtin = @import("builtin");
const separator = if (builtin.os.tag == .windows) '\\' else '/';
{#code_end#}
@@ -10526,7 +10525,7 @@ const separator = if (builtin.os.tag == .windows) '\\' else '/';
{#header_open|Building an Executable#}
<p>This <code class="file">build.zig</code> file is automatically generated
by <kbd>zig init-exe</kbd>.</p>
- {#code_begin|syntax|build#}
+ {#code_begin|syntax|build_executable#}
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
@@ -10560,7 +10559,7 @@ pub fn build(b: *Builder) void {
{#header_open|Building a Library#}
<p>This <code class="file">build.zig</code> file is automatically generated
by <kbd>zig init-lib</kbd>.</p>
- {#code_begin|syntax|build#}
+ {#code_begin|syntax|build_library#}
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
@@ -10622,7 +10621,7 @@ lib.addCSourceFile("src/lib.c", &[_][]const u8{
The {#syntax#}@cImport{#endsyntax#} builtin function can be used
to directly import symbols from <code class="file">.h</code> files:
</p>
- {#code_begin|exe#}
+ {#code_begin|exe|cImport_builtin#}
{#link_libc#}
const c = @cImport({
// See https://github.com/ziglang/zig/issues/515
@@ -10738,7 +10737,7 @@ pub extern fn do_something(foo: enum_FOO) c_int;{#end_shell_samp#}
To see where the cached files are stored when compiling code that uses {#syntax#}@cImport{#endsyntax#},
use the <kbd>--verbose-cimport</kbd> flag:
</p>
- {#code_begin|exe|verbose#}
+ {#code_begin|exe|verbose_cimport_flag#}
{#link_libc#}
{#code_verbose_cimport#}
const c = @cImport({
@@ -10856,7 +10855,7 @@ pub const MAKELOCAL = @compileError("unable to translate C expr: unexpected toke
{#header_open|C Variadic Functions#}
<p>Zig supports extern variadic functions.</p>
- {#code_begin|test|variadic_function#}
+ {#code_begin|test|test_variadic_function#}
{#link_libc#}
{#code_verbose_cimport#}
const std = @import("std");
@@ -10872,7 +10871,7 @@ test "variadic function" {
<p>
Variadic functions can be implemented using {#link|@cVaStart#}, {#link|@cVaEnd#}, {#link|@cVaArg#} and {#link|@cVaCopy#}
</p>
- {#code_begin|test|defining_variadic_function#}
+ {#code_begin|test|test_defining_variadic_function#}
const std = @import("std");
const testing = std.testing;
const builtin = @import("builtin");
@@ -10926,7 +10925,7 @@ int main(int argc, char **argv) {
return 0;
}
{#end_syntax_block#}
- {#code_begin|syntax|build#}
+ {#code_begin|syntax|build_c#}
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
@@ -10988,7 +10987,7 @@ int main(int argc, char **argv) {
return 0;
}
{#end_syntax_block#}
- {#code_begin|syntax|build#}
+ {#code_begin|syntax|build_object#}
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
@@ -11040,7 +11039,7 @@ The result is 3{#end_shell_samp#}
{#header_open|WASI#}
<p>Zig's support for WebAssembly System Interface (WASI) is under active development.
Example of using the standard library and reading command line arguments:</p>
- {#code_begin|exe|args#}
+ {#code_begin|exe|wasi_args#}
{#target_wasi#}
const std = @import("std");
@@ -11061,7 +11060,7 @@ pub fn main() !void {
2: hello{#end_shell_samp#}
<p>A more interesting example would be extracting the list of preopens from the runtime.
This is now supported in the standard library via {#syntax#}std.fs.wasi.PreopenList{#endsyntax#}:</p>
- {#code_begin|exe|preopens#}
+ {#code_begin|exe|wasi_preopens#}
{#target_wasi#}
const std = @import("std");
const fs = std.fs;
diff --git a/lib/std/build/InstallArtifactStep.zig b/lib/std/build/InstallArtifactStep.zig
index fbf2c36063..537b8c8fd9 100644
--- a/lib/std/build/InstallArtifactStep.zig
+++ b/lib/std/build/InstallArtifactStep.zig
@@ -81,8 +81,8 @@ fn make(step: *Step) !void {
try builder.updateFile(self.artifact.getOutputPdbSource().getPath(builder), full_pdb_path);
}
if (self.h_dir) |h_dir| {
- const full_pdb_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename);
- try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_pdb_path);
+ const full_h_path = builder.getInstallPath(h_dir, self.artifact.out_h_filename);
+ try builder.updateFile(self.artifact.getOutputHSource().getPath(builder), full_h_path);
}
self.artifact.installed_path = full_dest_path;
}
diff --git a/lib/std/crypto/Certificate.zig b/lib/std/crypto/Certificate.zig
index bdf4c6ecf0..3b491fa32e 100644
--- a/lib/std/crypto/Certificate.zig
+++ b/lib/std/crypto/Certificate.zig
@@ -95,6 +95,14 @@ pub const NamedCurve = enum {
.{ &[_]u8{ 0x2B, 0x81, 0x04, 0x00, 0x23 }, .secp521r1 },
.{ &[_]u8{ 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07 }, .X9_62_prime256v1 },
});
+
+ pub fn Curve(comptime curve: NamedCurve) type {
+ return switch (curve) {
+ .X9_62_prime256v1 => crypto.ecc.P256,
+ .secp384r1 => crypto.ecc.P384,
+ .secp521r1 => @compileError("unimplemented"),
+ };
+ }
};
pub const ExtensionId = enum {
@@ -783,9 +791,10 @@ fn verify_ecdsa(
.secp521r1 => {
return error.CertificateSignatureNamedCurveUnsupported;
},
- .secp384r1 => {
- const P = crypto.ecc.P384;
- const Ecdsa = crypto.sign.ecdsa.Ecdsa(P, Hash);
+ inline .X9_62_prime256v1,
+ .secp384r1,
+ => |curve| {
+ const Ecdsa = crypto.sign.ecdsa.Ecdsa(curve.Curve(), Hash);
const sig = Ecdsa.Signature.fromDer(encoded_sig) catch |err| switch (err) {
error.InvalidEncoding => return error.CertificateSignatureInvalid,
};
@@ -800,9 +809,6 @@ fn verify_ecdsa(
error.SignatureVerificationFailed => return error.CertificateSignatureInvalid,
};
},
- .X9_62_prime256v1 => {
- return error.CertificateSignatureNamedCurveUnsupported;
- },
}
}
diff --git a/lib/std/hash/crc.zig b/lib/std/hash/crc.zig
index ad2e0018c9..1c69978f80 100644
--- a/lib/std/hash/crc.zig
+++ b/lib/std/hash/crc.zig
@@ -10,6 +10,102 @@ const builtin = @import("builtin");
const debug = std.debug;
const testing = std.testing;
+pub usingnamespace @import("crc/catalog.zig");
+
+pub fn Algorithm(comptime W: type) type {
+ return struct {
+ polynomial: W,
+ initial: W,
+ reflect_input: bool,
+ reflect_output: bool,
+ xor_output: W,
+ };
+}
+
+pub fn Crc(comptime W: type, comptime algorithm: Algorithm(W)) type {
+ return struct {
+ const Self = @This();
+ const I = if (@bitSizeOf(W) < 8) u8 else W;
+ const lookup_table = blk: {
+ @setEvalBranchQuota(2500);
+
+ const poly = if (algorithm.reflect_input)
+ @bitReverse(@as(I, algorithm.polynomial)) >> (@bitSizeOf(I) - @bitSizeOf(W))
+ else
+ @as(I, algorithm.polynomial) << (@bitSizeOf(I) - @bitSizeOf(W));
+
+ var table: [256]I = undefined;
+ for (table) |*e, i| {
+ var crc: I = i;
+ if (algorithm.reflect_input) {
+ var j: usize = 0;
+ while (j < 8) : (j += 1) {
+ crc = (crc >> 1) ^ ((crc & 1) * poly);
+ }
+ } else {
+ crc <<= @bitSizeOf(I) - 8;
+ var j: usize = 0;
+ while (j < 8) : (j += 1) {
+ crc = (crc << 1) ^ (((crc >> (@bitSizeOf(I) - 1)) & 1) * poly);
+ }
+ }
+ e.* = crc;
+ }
+ break :blk table;
+ };
+
+ crc: I,
+
+ pub fn init() Self {
+ const initial = if (algorithm.reflect_input)
+ @bitReverse(@as(I, algorithm.initial)) >> (@bitSizeOf(I) - @bitSizeOf(W))
+ else
+ @as(I, algorithm.initial) << (@bitSizeOf(I) - @bitSizeOf(W));
+ return Self{ .crc = initial };
+ }
+
+ inline fn tableEntry(index: I) I {
+ return lookup_table[@intCast(u8, index & 0xFF)];
+ }
+
+ pub fn update(self: *Self, bytes: []const u8) void {
+ var i: usize = 0;
+ if (@bitSizeOf(I) <= 8) {
+ while (i < bytes.len) : (i += 1) {
+ self.crc = tableEntry(self.crc ^ bytes[i]);
+ }
+ } else if (algorithm.reflect_input) {
+ while (i < bytes.len) : (i += 1) {
+ const table_index = self.crc ^ bytes[i];
+ self.crc = tableEntry(table_index) ^ (self.crc >> 8);
+ }
+ } else {
+ while (i < bytes.len) : (i += 1) {
+ const table_index = (self.crc >> (@bitSizeOf(I) - 8)) ^ bytes[i];
+ self.crc = tableEntry(table_index) ^ (self.crc << 8);
+ }
+ }
+ }
+
+ pub fn final(self: Self) W {
+ var c = self.crc;
+ if (algorithm.reflect_input != algorithm.reflect_output) {
+ c = @bitReverse(c);
+ }
+ if (!algorithm.reflect_output) {
+ c >>= @bitSizeOf(I) - @bitSizeOf(W);
+ }
+ return @intCast(W, c ^ algorithm.xor_output);
+ }
+
+ pub fn hash(bytes: []const u8) W {
+ var c = Self.init();
+ c.update(bytes);
+ return c.final();
+ }
+ };
+}
+
pub const Polynomial = enum(u32) {
IEEE = 0xedb88320,
Castagnoli = 0x82f63b78,
diff --git a/lib/std/hash/crc/catalog.zig b/lib/std/hash/crc/catalog.zig
new file mode 100644
index 0000000000..ed08accce6
--- /dev/null
+++ b/lib/std/hash/crc/catalog.zig
@@ -0,0 +1,903 @@
+//! This file is auto-generated by tools/update_crc_catalog.zig.
+
+const Crc = @import("../crc.zig").Crc;
+
+test {
+ _ = @import("catalog_test.zig");
+}
+
+pub const Crc3Gsm = Crc(u3, .{
+ .polynomial = 0x3,
+ .initial = 0x0,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x7,
+});
+
+pub const Crc3Rohc = Crc(u3, .{
+ .polynomial = 0x3,
+ .initial = 0x7,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0,
+});
+
+pub const Crc4G704 = Crc(u4, .{
+ .polynomial = 0x3,
+ .initial = 0x0,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0,
+});
+
+pub const Crc4Interlaken = Crc(u4, .{
+ .polynomial = 0x3,
+ .initial = 0xf,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xf,
+});
+
+pub const Crc5EpcC1g2 = Crc(u5, .{
+ .polynomial = 0x09,
+ .initial = 0x09,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc5G704 = Crc(u5, .{
+ .polynomial = 0x15,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc5Usb = Crc(u5, .{
+ .polynomial = 0x05,
+ .initial = 0x1f,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x1f,
+});
+
+pub const Crc6Cdma2000A = Crc(u6, .{
+ .polynomial = 0x27,
+ .initial = 0x3f,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc6Cdma2000B = Crc(u6, .{
+ .polynomial = 0x07,
+ .initial = 0x3f,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc6Darc = Crc(u6, .{
+ .polynomial = 0x19,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc6G704 = Crc(u6, .{
+ .polynomial = 0x03,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc6Gsm = Crc(u6, .{
+ .polynomial = 0x2f,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x3f,
+});
+
+pub const Crc7Mmc = Crc(u7, .{
+ .polynomial = 0x09,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc7Rohc = Crc(u7, .{
+ .polynomial = 0x4f,
+ .initial = 0x7f,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc7Umts = Crc(u7, .{
+ .polynomial = 0x45,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Autosar = Crc(u8, .{
+ .polynomial = 0x2f,
+ .initial = 0xff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xff,
+});
+
+pub const Crc8Bluetooth = Crc(u8, .{
+ .polynomial = 0xa7,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Cdma2000 = Crc(u8, .{
+ .polynomial = 0x9b,
+ .initial = 0xff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Darc = Crc(u8, .{
+ .polynomial = 0x39,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc8DvbS2 = Crc(u8, .{
+ .polynomial = 0xd5,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8GsmA = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8GsmB = Crc(u8, .{
+ .polynomial = 0x49,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xff,
+});
+
+pub const Crc8Hitag = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0xff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8I4321 = Crc(u8, .{
+ .polynomial = 0x07,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x55,
+});
+
+pub const Crc8ICode = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0xfd,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Lte = Crc(u8, .{
+ .polynomial = 0x9b,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8MaximDow = Crc(u8, .{
+ .polynomial = 0x31,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc8MifareMad = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0xc7,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Nrsc5 = Crc(u8, .{
+ .polynomial = 0x31,
+ .initial = 0xff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Opensafety = Crc(u8, .{
+ .polynomial = 0x2f,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Rohc = Crc(u8, .{
+ .polynomial = 0x07,
+ .initial = 0xff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc8SaeJ1850 = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0xff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xff,
+});
+
+pub const Crc8Smbus = Crc(u8, .{
+ .polynomial = 0x07,
+ .initial = 0x00,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Tech3250 = Crc(u8, .{
+ .polynomial = 0x1d,
+ .initial = 0xff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc8Wcdma = Crc(u8, .{
+ .polynomial = 0x9b,
+ .initial = 0x00,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00,
+});
+
+pub const Crc10Atm = Crc(u10, .{
+ .polynomial = 0x233,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc10Cdma2000 = Crc(u10, .{
+ .polynomial = 0x3d9,
+ .initial = 0x3ff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc10Gsm = Crc(u10, .{
+ .polynomial = 0x175,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x3ff,
+});
+
+pub const Crc11Flexray = Crc(u11, .{
+ .polynomial = 0x385,
+ .initial = 0x01a,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc11Umts = Crc(u11, .{
+ .polynomial = 0x307,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc12Cdma2000 = Crc(u12, .{
+ .polynomial = 0xf13,
+ .initial = 0xfff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc12Dect = Crc(u12, .{
+ .polynomial = 0x80f,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000,
+});
+
+pub const Crc12Gsm = Crc(u12, .{
+ .polynomial = 0xd31,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xfff,
+});
+
+pub const Crc12Umts = Crc(u12, .{
+ .polynomial = 0x80f,
+ .initial = 0x000,
+ .reflect_input = false,
+ .reflect_output = true,
+ .xor_output = 0x000,
+});
+
+pub const Crc13Bbc = Crc(u13, .{
+ .polynomial = 0x1cf5,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc14Darc = Crc(u14, .{
+ .polynomial = 0x0805,
+ .initial = 0x0000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc14Gsm = Crc(u14, .{
+ .polynomial = 0x202d,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x3fff,
+});
+
+pub const Crc15Can = Crc(u15, .{
+ .polynomial = 0x4599,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc15Mpt1327 = Crc(u15, .{
+ .polynomial = 0x6815,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0001,
+});
+
+pub const Crc16Arc = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0x0000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Cdma2000 = Crc(u16, .{
+ .polynomial = 0xc867,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Cms = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Dds110 = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0x800d,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16DectR = Crc(u16, .{
+ .polynomial = 0x0589,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0001,
+});
+
+pub const Crc16DectX = Crc(u16, .{
+ .polynomial = 0x0589,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Dnp = Crc(u16, .{
+ .polynomial = 0x3d65,
+ .initial = 0x0000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16En13757 = Crc(u16, .{
+ .polynomial = 0x3d65,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Genibus = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Gsm = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Ibm3740 = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16IbmSdlc = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16IsoIec144433A = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xc6c6,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Kermit = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0x0000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Lj1200 = Crc(u16, .{
+ .polynomial = 0x6f63,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16M17 = Crc(u16, .{
+ .polynomial = 0x5935,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16MaximDow = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0x0000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Mcrf4xx = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Modbus = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0xffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Nrsc5 = Crc(u16, .{
+ .polynomial = 0x080b,
+ .initial = 0xffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16OpensafetyA = Crc(u16, .{
+ .polynomial = 0x5935,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16OpensafetyB = Crc(u16, .{
+ .polynomial = 0x755b,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Profibus = Crc(u16, .{
+ .polynomial = 0x1dcf,
+ .initial = 0xffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Riello = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0xb2aa,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16SpiFujitsu = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0x1d0f,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16T10Dif = Crc(u16, .{
+ .polynomial = 0x8bb7,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Teledisk = Crc(u16, .{
+ .polynomial = 0xa097,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Tms37157 = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0x89ec,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Umts = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc16Usb = Crc(u16, .{
+ .polynomial = 0x8005,
+ .initial = 0xffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffff,
+});
+
+pub const Crc16Xmodem = Crc(u16, .{
+ .polynomial = 0x1021,
+ .initial = 0x0000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000,
+});
+
+pub const Crc17CanFd = Crc(u17, .{
+ .polynomial = 0x1685b,
+ .initial = 0x00000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00000,
+});
+
+pub const Crc21CanFd = Crc(u21, .{
+ .polynomial = 0x102899,
+ .initial = 0x000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24Ble = Crc(u24, .{
+ .polynomial = 0x00065b,
+ .initial = 0x555555,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24FlexrayA = Crc(u24, .{
+ .polynomial = 0x5d6dcb,
+ .initial = 0xfedcba,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24FlexrayB = Crc(u24, .{
+ .polynomial = 0x5d6dcb,
+ .initial = 0xabcdef,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24Interlaken = Crc(u24, .{
+ .polynomial = 0x328b63,
+ .initial = 0xffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffff,
+});
+
+pub const Crc24LteA = Crc(u24, .{
+ .polynomial = 0x864cfb,
+ .initial = 0x000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24LteB = Crc(u24, .{
+ .polynomial = 0x800063,
+ .initial = 0x000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24Openpgp = Crc(u24, .{
+ .polynomial = 0x864cfb,
+ .initial = 0xb704ce,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x000000,
+});
+
+pub const Crc24Os9 = Crc(u24, .{
+ .polynomial = 0x800063,
+ .initial = 0xffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffff,
+});
+
+pub const Crc30Cdma = Crc(u30, .{
+ .polynomial = 0x2030b9c7,
+ .initial = 0x3fffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x3fffffff,
+});
+
+pub const Crc31Philips = Crc(u31, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0x7fffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x7fffffff,
+});
+
+pub const Crc32Aixm = Crc(u32, .{
+ .polynomial = 0x814141ab,
+ .initial = 0x00000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc32Autosar = Crc(u32, .{
+ .polynomial = 0xf4acfb13,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32Base91D = Crc(u32, .{
+ .polynomial = 0xa833982b,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32Bzip2 = Crc(u32, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0xffffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32CdRomEdc = Crc(u32, .{
+ .polynomial = 0x8001801b,
+ .initial = 0x00000000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc32Cksum = Crc(u32, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0x00000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32Iscsi = Crc(u32, .{
+ .polynomial = 0x1edc6f41,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32IsoHdlc = Crc(u32, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffff,
+});
+
+pub const Crc32Jamcrc = Crc(u32, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc32Mef = Crc(u32, .{
+ .polynomial = 0x741b8cd7,
+ .initial = 0xffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc32Mpeg2 = Crc(u32, .{
+ .polynomial = 0x04c11db7,
+ .initial = 0xffffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc32Xfer = Crc(u32, .{
+ .polynomial = 0x000000af,
+ .initial = 0x00000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x00000000,
+});
+
+pub const Crc40Gsm = Crc(u40, .{
+ .polynomial = 0x0004820009,
+ .initial = 0x0000000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffffffff,
+});
+
+pub const Crc64Ecma182 = Crc(u64, .{
+ .polynomial = 0x42f0e1eba9ea3693,
+ .initial = 0x0000000000000000,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0x0000000000000000,
+});
+
+pub const Crc64GoIso = Crc(u64, .{
+ .polynomial = 0x000000000000001b,
+ .initial = 0xffffffffffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffffffffffff,
+});
+
+pub const Crc64Ms = Crc(u64, .{
+ .polynomial = 0x259c84cba6426349,
+ .initial = 0xffffffffffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000000000000000,
+});
+
+pub const Crc64Redis = Crc(u64, .{
+ .polynomial = 0xad93d23594c935a9,
+ .initial = 0x0000000000000000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x0000000000000000,
+});
+
+pub const Crc64We = Crc(u64, .{
+ .polynomial = 0x42f0e1eba9ea3693,
+ .initial = 0xffffffffffffffff,
+ .reflect_input = false,
+ .reflect_output = false,
+ .xor_output = 0xffffffffffffffff,
+});
+
+pub const Crc64Xz = Crc(u64, .{
+ .polynomial = 0x42f0e1eba9ea3693,
+ .initial = 0xffffffffffffffff,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0xffffffffffffffff,
+});
+
+pub const Crc82Darc = Crc(u82, .{
+ .polynomial = 0x0308c0111011401440411,
+ .initial = 0x000000000000000000000,
+ .reflect_input = true,
+ .reflect_output = true,
+ .xor_output = 0x000000000000000000000,
+});
diff --git a/lib/std/hash/crc/catalog_test.zig b/lib/std/hash/crc/catalog_test.zig
new file mode 100644
index 0000000000..b9bf21fc99
--- /dev/null
+++ b/lib/std/hash/crc/catalog_test.zig
@@ -0,0 +1,1237 @@
+//! This file is auto-generated by tools/update_crc_catalog.zig.
+
+const std = @import("../../std.zig");
+const testing = std.testing;
+const catalog = @import("catalog.zig");
+
+test "CRC-3/GSM" {
+ const Crc3Gsm = catalog.Crc3Gsm;
+
+ try testing.expectEqual(@as(u3, 0x4), Crc3Gsm.hash("123456789"));
+
+ var c = Crc3Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u3, 0x4), c.final());
+}
+
+test "CRC-3/ROHC" {
+ const Crc3Rohc = catalog.Crc3Rohc;
+
+ try testing.expectEqual(@as(u3, 0x6), Crc3Rohc.hash("123456789"));
+
+ var c = Crc3Rohc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u3, 0x6), c.final());
+}
+
+test "CRC-4/G-704" {
+ const Crc4G704 = catalog.Crc4G704;
+
+ try testing.expectEqual(@as(u4, 0x7), Crc4G704.hash("123456789"));
+
+ var c = Crc4G704.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u4, 0x7), c.final());
+}
+
+test "CRC-4/INTERLAKEN" {
+ const Crc4Interlaken = catalog.Crc4Interlaken;
+
+ try testing.expectEqual(@as(u4, 0xb), Crc4Interlaken.hash("123456789"));
+
+ var c = Crc4Interlaken.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u4, 0xb), c.final());
+}
+
+test "CRC-5/EPC-C1G2" {
+ const Crc5EpcC1g2 = catalog.Crc5EpcC1g2;
+
+ try testing.expectEqual(@as(u5, 0x00), Crc5EpcC1g2.hash("123456789"));
+
+ var c = Crc5EpcC1g2.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u5, 0x00), c.final());
+}
+
+test "CRC-5/G-704" {
+ const Crc5G704 = catalog.Crc5G704;
+
+ try testing.expectEqual(@as(u5, 0x07), Crc5G704.hash("123456789"));
+
+ var c = Crc5G704.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u5, 0x07), c.final());
+}
+
+test "CRC-5/USB" {
+ const Crc5Usb = catalog.Crc5Usb;
+
+ try testing.expectEqual(@as(u5, 0x19), Crc5Usb.hash("123456789"));
+
+ var c = Crc5Usb.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u5, 0x19), c.final());
+}
+
+test "CRC-6/CDMA2000-A" {
+ const Crc6Cdma2000A = catalog.Crc6Cdma2000A;
+
+ try testing.expectEqual(@as(u6, 0x0d), Crc6Cdma2000A.hash("123456789"));
+
+ var c = Crc6Cdma2000A.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u6, 0x0d), c.final());
+}
+
+test "CRC-6/CDMA2000-B" {
+ const Crc6Cdma2000B = catalog.Crc6Cdma2000B;
+
+ try testing.expectEqual(@as(u6, 0x3b), Crc6Cdma2000B.hash("123456789"));
+
+ var c = Crc6Cdma2000B.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u6, 0x3b), c.final());
+}
+
+test "CRC-6/DARC" {
+ const Crc6Darc = catalog.Crc6Darc;
+
+ try testing.expectEqual(@as(u6, 0x26), Crc6Darc.hash("123456789"));
+
+ var c = Crc6Darc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u6, 0x26), c.final());
+}
+
+test "CRC-6/G-704" {
+ const Crc6G704 = catalog.Crc6G704;
+
+ try testing.expectEqual(@as(u6, 0x06), Crc6G704.hash("123456789"));
+
+ var c = Crc6G704.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u6, 0x06), c.final());
+}
+
+test "CRC-6/GSM" {
+ const Crc6Gsm = catalog.Crc6Gsm;
+
+ try testing.expectEqual(@as(u6, 0x13), Crc6Gsm.hash("123456789"));
+
+ var c = Crc6Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u6, 0x13), c.final());
+}
+
+test "CRC-7/MMC" {
+ const Crc7Mmc = catalog.Crc7Mmc;
+
+ try testing.expectEqual(@as(u7, 0x75), Crc7Mmc.hash("123456789"));
+
+ var c = Crc7Mmc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u7, 0x75), c.final());
+}
+
+test "CRC-7/ROHC" {
+ const Crc7Rohc = catalog.Crc7Rohc;
+
+ try testing.expectEqual(@as(u7, 0x53), Crc7Rohc.hash("123456789"));
+
+ var c = Crc7Rohc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u7, 0x53), c.final());
+}
+
+test "CRC-7/UMTS" {
+ const Crc7Umts = catalog.Crc7Umts;
+
+ try testing.expectEqual(@as(u7, 0x61), Crc7Umts.hash("123456789"));
+
+ var c = Crc7Umts.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u7, 0x61), c.final());
+}
+
+test "CRC-8/AUTOSAR" {
+ const Crc8Autosar = catalog.Crc8Autosar;
+
+ try testing.expectEqual(@as(u8, 0xdf), Crc8Autosar.hash("123456789"));
+
+ var c = Crc8Autosar.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xdf), c.final());
+}
+
+test "CRC-8/BLUETOOTH" {
+ const Crc8Bluetooth = catalog.Crc8Bluetooth;
+
+ try testing.expectEqual(@as(u8, 0x26), Crc8Bluetooth.hash("123456789"));
+
+ var c = Crc8Bluetooth.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x26), c.final());
+}
+
+test "CRC-8/CDMA2000" {
+ const Crc8Cdma2000 = catalog.Crc8Cdma2000;
+
+ try testing.expectEqual(@as(u8, 0xda), Crc8Cdma2000.hash("123456789"));
+
+ var c = Crc8Cdma2000.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xda), c.final());
+}
+
+test "CRC-8/DARC" {
+ const Crc8Darc = catalog.Crc8Darc;
+
+ try testing.expectEqual(@as(u8, 0x15), Crc8Darc.hash("123456789"));
+
+ var c = Crc8Darc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x15), c.final());
+}
+
+test "CRC-8/DVB-S2" {
+ const Crc8DvbS2 = catalog.Crc8DvbS2;
+
+ try testing.expectEqual(@as(u8, 0xbc), Crc8DvbS2.hash("123456789"));
+
+ var c = Crc8DvbS2.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xbc), c.final());
+}
+
+test "CRC-8/GSM-A" {
+ const Crc8GsmA = catalog.Crc8GsmA;
+
+ try testing.expectEqual(@as(u8, 0x37), Crc8GsmA.hash("123456789"));
+
+ var c = Crc8GsmA.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x37), c.final());
+}
+
+test "CRC-8/GSM-B" {
+ const Crc8GsmB = catalog.Crc8GsmB;
+
+ try testing.expectEqual(@as(u8, 0x94), Crc8GsmB.hash("123456789"));
+
+ var c = Crc8GsmB.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x94), c.final());
+}
+
+test "CRC-8/HITAG" {
+ const Crc8Hitag = catalog.Crc8Hitag;
+
+ try testing.expectEqual(@as(u8, 0xb4), Crc8Hitag.hash("123456789"));
+
+ var c = Crc8Hitag.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xb4), c.final());
+}
+
+test "CRC-8/I-432-1" {
+ const Crc8I4321 = catalog.Crc8I4321;
+
+ try testing.expectEqual(@as(u8, 0xa1), Crc8I4321.hash("123456789"));
+
+ var c = Crc8I4321.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xa1), c.final());
+}
+
+test "CRC-8/I-CODE" {
+ const Crc8ICode = catalog.Crc8ICode;
+
+ try testing.expectEqual(@as(u8, 0x7e), Crc8ICode.hash("123456789"));
+
+ var c = Crc8ICode.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x7e), c.final());
+}
+
+test "CRC-8/LTE" {
+ const Crc8Lte = catalog.Crc8Lte;
+
+ try testing.expectEqual(@as(u8, 0xea), Crc8Lte.hash("123456789"));
+
+ var c = Crc8Lte.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xea), c.final());
+}
+
+test "CRC-8/MAXIM-DOW" {
+ const Crc8MaximDow = catalog.Crc8MaximDow;
+
+ try testing.expectEqual(@as(u8, 0xa1), Crc8MaximDow.hash("123456789"));
+
+ var c = Crc8MaximDow.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xa1), c.final());
+}
+
+test "CRC-8/MIFARE-MAD" {
+ const Crc8MifareMad = catalog.Crc8MifareMad;
+
+ try testing.expectEqual(@as(u8, 0x99), Crc8MifareMad.hash("123456789"));
+
+ var c = Crc8MifareMad.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x99), c.final());
+}
+
+test "CRC-8/NRSC-5" {
+ const Crc8Nrsc5 = catalog.Crc8Nrsc5;
+
+ try testing.expectEqual(@as(u8, 0xf7), Crc8Nrsc5.hash("123456789"));
+
+ var c = Crc8Nrsc5.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xf7), c.final());
+}
+
+test "CRC-8/OPENSAFETY" {
+ const Crc8Opensafety = catalog.Crc8Opensafety;
+
+ try testing.expectEqual(@as(u8, 0x3e), Crc8Opensafety.hash("123456789"));
+
+ var c = Crc8Opensafety.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x3e), c.final());
+}
+
+test "CRC-8/ROHC" {
+ const Crc8Rohc = catalog.Crc8Rohc;
+
+ try testing.expectEqual(@as(u8, 0xd0), Crc8Rohc.hash("123456789"));
+
+ var c = Crc8Rohc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xd0), c.final());
+}
+
+test "CRC-8/SAE-J1850" {
+ const Crc8SaeJ1850 = catalog.Crc8SaeJ1850;
+
+ try testing.expectEqual(@as(u8, 0x4b), Crc8SaeJ1850.hash("123456789"));
+
+ var c = Crc8SaeJ1850.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x4b), c.final());
+}
+
+test "CRC-8/SMBUS" {
+ const Crc8Smbus = catalog.Crc8Smbus;
+
+ try testing.expectEqual(@as(u8, 0xf4), Crc8Smbus.hash("123456789"));
+
+ var c = Crc8Smbus.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0xf4), c.final());
+}
+
+test "CRC-8/TECH-3250" {
+ const Crc8Tech3250 = catalog.Crc8Tech3250;
+
+ try testing.expectEqual(@as(u8, 0x97), Crc8Tech3250.hash("123456789"));
+
+ var c = Crc8Tech3250.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x97), c.final());
+}
+
+test "CRC-8/WCDMA" {
+ const Crc8Wcdma = catalog.Crc8Wcdma;
+
+ try testing.expectEqual(@as(u8, 0x25), Crc8Wcdma.hash("123456789"));
+
+ var c = Crc8Wcdma.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u8, 0x25), c.final());
+}
+
+test "CRC-10/ATM" {
+ const Crc10Atm = catalog.Crc10Atm;
+
+ try testing.expectEqual(@as(u10, 0x199), Crc10Atm.hash("123456789"));
+
+ var c = Crc10Atm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u10, 0x199), c.final());
+}
+
+test "CRC-10/CDMA2000" {
+ const Crc10Cdma2000 = catalog.Crc10Cdma2000;
+
+ try testing.expectEqual(@as(u10, 0x233), Crc10Cdma2000.hash("123456789"));
+
+ var c = Crc10Cdma2000.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u10, 0x233), c.final());
+}
+
+test "CRC-10/GSM" {
+ const Crc10Gsm = catalog.Crc10Gsm;
+
+ try testing.expectEqual(@as(u10, 0x12a), Crc10Gsm.hash("123456789"));
+
+ var c = Crc10Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u10, 0x12a), c.final());
+}
+
+test "CRC-11/FLEXRAY" {
+ const Crc11Flexray = catalog.Crc11Flexray;
+
+ try testing.expectEqual(@as(u11, 0x5a3), Crc11Flexray.hash("123456789"));
+
+ var c = Crc11Flexray.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u11, 0x5a3), c.final());
+}
+
+test "CRC-11/UMTS" {
+ const Crc11Umts = catalog.Crc11Umts;
+
+ try testing.expectEqual(@as(u11, 0x061), Crc11Umts.hash("123456789"));
+
+ var c = Crc11Umts.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u11, 0x061), c.final());
+}
+
+test "CRC-12/CDMA2000" {
+ const Crc12Cdma2000 = catalog.Crc12Cdma2000;
+
+ try testing.expectEqual(@as(u12, 0xd4d), Crc12Cdma2000.hash("123456789"));
+
+ var c = Crc12Cdma2000.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u12, 0xd4d), c.final());
+}
+
+test "CRC-12/DECT" {
+ const Crc12Dect = catalog.Crc12Dect;
+
+ try testing.expectEqual(@as(u12, 0xf5b), Crc12Dect.hash("123456789"));
+
+ var c = Crc12Dect.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u12, 0xf5b), c.final());
+}
+
+test "CRC-12/GSM" {
+ const Crc12Gsm = catalog.Crc12Gsm;
+
+ try testing.expectEqual(@as(u12, 0xb34), Crc12Gsm.hash("123456789"));
+
+ var c = Crc12Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u12, 0xb34), c.final());
+}
+
+test "CRC-12/UMTS" {
+ const Crc12Umts = catalog.Crc12Umts;
+
+ try testing.expectEqual(@as(u12, 0xdaf), Crc12Umts.hash("123456789"));
+
+ var c = Crc12Umts.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u12, 0xdaf), c.final());
+}
+
+test "CRC-13/BBC" {
+ const Crc13Bbc = catalog.Crc13Bbc;
+
+ try testing.expectEqual(@as(u13, 0x04fa), Crc13Bbc.hash("123456789"));
+
+ var c = Crc13Bbc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u13, 0x04fa), c.final());
+}
+
+test "CRC-14/DARC" {
+ const Crc14Darc = catalog.Crc14Darc;
+
+ try testing.expectEqual(@as(u14, 0x082d), Crc14Darc.hash("123456789"));
+
+ var c = Crc14Darc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u14, 0x082d), c.final());
+}
+
+test "CRC-14/GSM" {
+ const Crc14Gsm = catalog.Crc14Gsm;
+
+ try testing.expectEqual(@as(u14, 0x30ae), Crc14Gsm.hash("123456789"));
+
+ var c = Crc14Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u14, 0x30ae), c.final());
+}
+
+test "CRC-15/CAN" {
+ const Crc15Can = catalog.Crc15Can;
+
+ try testing.expectEqual(@as(u15, 0x059e), Crc15Can.hash("123456789"));
+
+ var c = Crc15Can.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u15, 0x059e), c.final());
+}
+
+test "CRC-15/MPT1327" {
+ const Crc15Mpt1327 = catalog.Crc15Mpt1327;
+
+ try testing.expectEqual(@as(u15, 0x2566), Crc15Mpt1327.hash("123456789"));
+
+ var c = Crc15Mpt1327.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u15, 0x2566), c.final());
+}
+
+test "CRC-16/ARC" {
+ const Crc16Arc = catalog.Crc16Arc;
+
+ try testing.expectEqual(@as(u16, 0xbb3d), Crc16Arc.hash("123456789"));
+
+ var c = Crc16Arc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xbb3d), c.final());
+}
+
+test "CRC-16/CDMA2000" {
+ const Crc16Cdma2000 = catalog.Crc16Cdma2000;
+
+ try testing.expectEqual(@as(u16, 0x4c06), Crc16Cdma2000.hash("123456789"));
+
+ var c = Crc16Cdma2000.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x4c06), c.final());
+}
+
+test "CRC-16/CMS" {
+ const Crc16Cms = catalog.Crc16Cms;
+
+ try testing.expectEqual(@as(u16, 0xaee7), Crc16Cms.hash("123456789"));
+
+ var c = Crc16Cms.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xaee7), c.final());
+}
+
+test "CRC-16/DDS-110" {
+ const Crc16Dds110 = catalog.Crc16Dds110;
+
+ try testing.expectEqual(@as(u16, 0x9ecf), Crc16Dds110.hash("123456789"));
+
+ var c = Crc16Dds110.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x9ecf), c.final());
+}
+
+test "CRC-16/DECT-R" {
+ const Crc16DectR = catalog.Crc16DectR;
+
+ try testing.expectEqual(@as(u16, 0x007e), Crc16DectR.hash("123456789"));
+
+ var c = Crc16DectR.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x007e), c.final());
+}
+
+test "CRC-16/DECT-X" {
+ const Crc16DectX = catalog.Crc16DectX;
+
+ try testing.expectEqual(@as(u16, 0x007f), Crc16DectX.hash("123456789"));
+
+ var c = Crc16DectX.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x007f), c.final());
+}
+
+test "CRC-16/DNP" {
+ const Crc16Dnp = catalog.Crc16Dnp;
+
+ try testing.expectEqual(@as(u16, 0xea82), Crc16Dnp.hash("123456789"));
+
+ var c = Crc16Dnp.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xea82), c.final());
+}
+
+test "CRC-16/EN-13757" {
+ const Crc16En13757 = catalog.Crc16En13757;
+
+ try testing.expectEqual(@as(u16, 0xc2b7), Crc16En13757.hash("123456789"));
+
+ var c = Crc16En13757.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xc2b7), c.final());
+}
+
+test "CRC-16/GENIBUS" {
+ const Crc16Genibus = catalog.Crc16Genibus;
+
+ try testing.expectEqual(@as(u16, 0xd64e), Crc16Genibus.hash("123456789"));
+
+ var c = Crc16Genibus.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xd64e), c.final());
+}
+
+test "CRC-16/GSM" {
+ const Crc16Gsm = catalog.Crc16Gsm;
+
+ try testing.expectEqual(@as(u16, 0xce3c), Crc16Gsm.hash("123456789"));
+
+ var c = Crc16Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xce3c), c.final());
+}
+
+test "CRC-16/IBM-3740" {
+ const Crc16Ibm3740 = catalog.Crc16Ibm3740;
+
+ try testing.expectEqual(@as(u16, 0x29b1), Crc16Ibm3740.hash("123456789"));
+
+ var c = Crc16Ibm3740.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x29b1), c.final());
+}
+
+test "CRC-16/IBM-SDLC" {
+ const Crc16IbmSdlc = catalog.Crc16IbmSdlc;
+
+ try testing.expectEqual(@as(u16, 0x906e), Crc16IbmSdlc.hash("123456789"));
+
+ var c = Crc16IbmSdlc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x906e), c.final());
+}
+
+test "CRC-16/ISO-IEC-14443-3-A" {
+ const Crc16IsoIec144433A = catalog.Crc16IsoIec144433A;
+
+ try testing.expectEqual(@as(u16, 0xbf05), Crc16IsoIec144433A.hash("123456789"));
+
+ var c = Crc16IsoIec144433A.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xbf05), c.final());
+}
+
+test "CRC-16/KERMIT" {
+ const Crc16Kermit = catalog.Crc16Kermit;
+
+ try testing.expectEqual(@as(u16, 0x2189), Crc16Kermit.hash("123456789"));
+
+ var c = Crc16Kermit.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x2189), c.final());
+}
+
+test "CRC-16/LJ1200" {
+ const Crc16Lj1200 = catalog.Crc16Lj1200;
+
+ try testing.expectEqual(@as(u16, 0xbdf4), Crc16Lj1200.hash("123456789"));
+
+ var c = Crc16Lj1200.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xbdf4), c.final());
+}
+
+test "CRC-16/M17" {
+ const Crc16M17 = catalog.Crc16M17;
+
+ try testing.expectEqual(@as(u16, 0x772b), Crc16M17.hash("123456789"));
+
+ var c = Crc16M17.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x772b), c.final());
+}
+
+test "CRC-16/MAXIM-DOW" {
+ const Crc16MaximDow = catalog.Crc16MaximDow;
+
+ try testing.expectEqual(@as(u16, 0x44c2), Crc16MaximDow.hash("123456789"));
+
+ var c = Crc16MaximDow.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x44c2), c.final());
+}
+
+test "CRC-16/MCRF4XX" {
+ const Crc16Mcrf4xx = catalog.Crc16Mcrf4xx;
+
+ try testing.expectEqual(@as(u16, 0x6f91), Crc16Mcrf4xx.hash("123456789"));
+
+ var c = Crc16Mcrf4xx.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x6f91), c.final());
+}
+
+test "CRC-16/MODBUS" {
+ const Crc16Modbus = catalog.Crc16Modbus;
+
+ try testing.expectEqual(@as(u16, 0x4b37), Crc16Modbus.hash("123456789"));
+
+ var c = Crc16Modbus.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x4b37), c.final());
+}
+
+test "CRC-16/NRSC-5" {
+ const Crc16Nrsc5 = catalog.Crc16Nrsc5;
+
+ try testing.expectEqual(@as(u16, 0xa066), Crc16Nrsc5.hash("123456789"));
+
+ var c = Crc16Nrsc5.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xa066), c.final());
+}
+
+test "CRC-16/OPENSAFETY-A" {
+ const Crc16OpensafetyA = catalog.Crc16OpensafetyA;
+
+ try testing.expectEqual(@as(u16, 0x5d38), Crc16OpensafetyA.hash("123456789"));
+
+ var c = Crc16OpensafetyA.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x5d38), c.final());
+}
+
+test "CRC-16/OPENSAFETY-B" {
+ const Crc16OpensafetyB = catalog.Crc16OpensafetyB;
+
+ try testing.expectEqual(@as(u16, 0x20fe), Crc16OpensafetyB.hash("123456789"));
+
+ var c = Crc16OpensafetyB.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x20fe), c.final());
+}
+
+test "CRC-16/PROFIBUS" {
+ const Crc16Profibus = catalog.Crc16Profibus;
+
+ try testing.expectEqual(@as(u16, 0xa819), Crc16Profibus.hash("123456789"));
+
+ var c = Crc16Profibus.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xa819), c.final());
+}
+
+test "CRC-16/RIELLO" {
+ const Crc16Riello = catalog.Crc16Riello;
+
+ try testing.expectEqual(@as(u16, 0x63d0), Crc16Riello.hash("123456789"));
+
+ var c = Crc16Riello.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x63d0), c.final());
+}
+
+test "CRC-16/SPI-FUJITSU" {
+ const Crc16SpiFujitsu = catalog.Crc16SpiFujitsu;
+
+ try testing.expectEqual(@as(u16, 0xe5cc), Crc16SpiFujitsu.hash("123456789"));
+
+ var c = Crc16SpiFujitsu.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xe5cc), c.final());
+}
+
+test "CRC-16/T10-DIF" {
+ const Crc16T10Dif = catalog.Crc16T10Dif;
+
+ try testing.expectEqual(@as(u16, 0xd0db), Crc16T10Dif.hash("123456789"));
+
+ var c = Crc16T10Dif.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xd0db), c.final());
+}
+
+test "CRC-16/TELEDISK" {
+ const Crc16Teledisk = catalog.Crc16Teledisk;
+
+ try testing.expectEqual(@as(u16, 0x0fb3), Crc16Teledisk.hash("123456789"));
+
+ var c = Crc16Teledisk.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x0fb3), c.final());
+}
+
+test "CRC-16/TMS37157" {
+ const Crc16Tms37157 = catalog.Crc16Tms37157;
+
+ try testing.expectEqual(@as(u16, 0x26b1), Crc16Tms37157.hash("123456789"));
+
+ var c = Crc16Tms37157.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x26b1), c.final());
+}
+
+test "CRC-16/UMTS" {
+ const Crc16Umts = catalog.Crc16Umts;
+
+ try testing.expectEqual(@as(u16, 0xfee8), Crc16Umts.hash("123456789"));
+
+ var c = Crc16Umts.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xfee8), c.final());
+}
+
+test "CRC-16/USB" {
+ const Crc16Usb = catalog.Crc16Usb;
+
+ try testing.expectEqual(@as(u16, 0xb4c8), Crc16Usb.hash("123456789"));
+
+ var c = Crc16Usb.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0xb4c8), c.final());
+}
+
+test "CRC-16/XMODEM" {
+ const Crc16Xmodem = catalog.Crc16Xmodem;
+
+ try testing.expectEqual(@as(u16, 0x31c3), Crc16Xmodem.hash("123456789"));
+
+ var c = Crc16Xmodem.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u16, 0x31c3), c.final());
+}
+
+test "CRC-17/CAN-FD" {
+ const Crc17CanFd = catalog.Crc17CanFd;
+
+ try testing.expectEqual(@as(u17, 0x04f03), Crc17CanFd.hash("123456789"));
+
+ var c = Crc17CanFd.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u17, 0x04f03), c.final());
+}
+
+test "CRC-21/CAN-FD" {
+ const Crc21CanFd = catalog.Crc21CanFd;
+
+ try testing.expectEqual(@as(u21, 0x0ed841), Crc21CanFd.hash("123456789"));
+
+ var c = Crc21CanFd.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u21, 0x0ed841), c.final());
+}
+
+test "CRC-24/BLE" {
+ const Crc24Ble = catalog.Crc24Ble;
+
+ try testing.expectEqual(@as(u24, 0xc25a56), Crc24Ble.hash("123456789"));
+
+ var c = Crc24Ble.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0xc25a56), c.final());
+}
+
+test "CRC-24/FLEXRAY-A" {
+ const Crc24FlexrayA = catalog.Crc24FlexrayA;
+
+ try testing.expectEqual(@as(u24, 0x7979bd), Crc24FlexrayA.hash("123456789"));
+
+ var c = Crc24FlexrayA.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0x7979bd), c.final());
+}
+
+test "CRC-24/FLEXRAY-B" {
+ const Crc24FlexrayB = catalog.Crc24FlexrayB;
+
+ try testing.expectEqual(@as(u24, 0x1f23b8), Crc24FlexrayB.hash("123456789"));
+
+ var c = Crc24FlexrayB.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0x1f23b8), c.final());
+}
+
+test "CRC-24/INTERLAKEN" {
+ const Crc24Interlaken = catalog.Crc24Interlaken;
+
+ try testing.expectEqual(@as(u24, 0xb4f3e6), Crc24Interlaken.hash("123456789"));
+
+ var c = Crc24Interlaken.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0xb4f3e6), c.final());
+}
+
+test "CRC-24/LTE-A" {
+ const Crc24LteA = catalog.Crc24LteA;
+
+ try testing.expectEqual(@as(u24, 0xcde703), Crc24LteA.hash("123456789"));
+
+ var c = Crc24LteA.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0xcde703), c.final());
+}
+
+test "CRC-24/LTE-B" {
+ const Crc24LteB = catalog.Crc24LteB;
+
+ try testing.expectEqual(@as(u24, 0x23ef52), Crc24LteB.hash("123456789"));
+
+ var c = Crc24LteB.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0x23ef52), c.final());
+}
+
+test "CRC-24/OPENPGP" {
+ const Crc24Openpgp = catalog.Crc24Openpgp;
+
+ try testing.expectEqual(@as(u24, 0x21cf02), Crc24Openpgp.hash("123456789"));
+
+ var c = Crc24Openpgp.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0x21cf02), c.final());
+}
+
+test "CRC-24/OS-9" {
+ const Crc24Os9 = catalog.Crc24Os9;
+
+ try testing.expectEqual(@as(u24, 0x200fa5), Crc24Os9.hash("123456789"));
+
+ var c = Crc24Os9.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u24, 0x200fa5), c.final());
+}
+
+test "CRC-30/CDMA" {
+ const Crc30Cdma = catalog.Crc30Cdma;
+
+ try testing.expectEqual(@as(u30, 0x04c34abf), Crc30Cdma.hash("123456789"));
+
+ var c = Crc30Cdma.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u30, 0x04c34abf), c.final());
+}
+
+test "CRC-31/PHILIPS" {
+ const Crc31Philips = catalog.Crc31Philips;
+
+ try testing.expectEqual(@as(u31, 0x0ce9e46c), Crc31Philips.hash("123456789"));
+
+ var c = Crc31Philips.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u31, 0x0ce9e46c), c.final());
+}
+
+test "CRC-32/AIXM" {
+ const Crc32Aixm = catalog.Crc32Aixm;
+
+ try testing.expectEqual(@as(u32, 0x3010bf7f), Crc32Aixm.hash("123456789"));
+
+ var c = Crc32Aixm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x3010bf7f), c.final());
+}
+
+test "CRC-32/AUTOSAR" {
+ const Crc32Autosar = catalog.Crc32Autosar;
+
+ try testing.expectEqual(@as(u32, 0x1697d06a), Crc32Autosar.hash("123456789"));
+
+ var c = Crc32Autosar.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x1697d06a), c.final());
+}
+
+test "CRC-32/BASE91-D" {
+ const Crc32Base91D = catalog.Crc32Base91D;
+
+ try testing.expectEqual(@as(u32, 0x87315576), Crc32Base91D.hash("123456789"));
+
+ var c = Crc32Base91D.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x87315576), c.final());
+}
+
+test "CRC-32/BZIP2" {
+ const Crc32Bzip2 = catalog.Crc32Bzip2;
+
+ try testing.expectEqual(@as(u32, 0xfc891918), Crc32Bzip2.hash("123456789"));
+
+ var c = Crc32Bzip2.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0xfc891918), c.final());
+}
+
+test "CRC-32/CD-ROM-EDC" {
+ const Crc32CdRomEdc = catalog.Crc32CdRomEdc;
+
+ try testing.expectEqual(@as(u32, 0x6ec2edc4), Crc32CdRomEdc.hash("123456789"));
+
+ var c = Crc32CdRomEdc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x6ec2edc4), c.final());
+}
+
+test "CRC-32/CKSUM" {
+ const Crc32Cksum = catalog.Crc32Cksum;
+
+ try testing.expectEqual(@as(u32, 0x765e7680), Crc32Cksum.hash("123456789"));
+
+ var c = Crc32Cksum.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x765e7680), c.final());
+}
+
+test "CRC-32/ISCSI" {
+ const Crc32Iscsi = catalog.Crc32Iscsi;
+
+ try testing.expectEqual(@as(u32, 0xe3069283), Crc32Iscsi.hash("123456789"));
+
+ var c = Crc32Iscsi.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0xe3069283), c.final());
+}
+
+test "CRC-32/ISO-HDLC" {
+ const Crc32IsoHdlc = catalog.Crc32IsoHdlc;
+
+ try testing.expectEqual(@as(u32, 0xcbf43926), Crc32IsoHdlc.hash("123456789"));
+
+ var c = Crc32IsoHdlc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0xcbf43926), c.final());
+}
+
+test "CRC-32/JAMCRC" {
+ const Crc32Jamcrc = catalog.Crc32Jamcrc;
+
+ try testing.expectEqual(@as(u32, 0x340bc6d9), Crc32Jamcrc.hash("123456789"));
+
+ var c = Crc32Jamcrc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x340bc6d9), c.final());
+}
+
+test "CRC-32/MEF" {
+ const Crc32Mef = catalog.Crc32Mef;
+
+ try testing.expectEqual(@as(u32, 0xd2c22f51), Crc32Mef.hash("123456789"));
+
+ var c = Crc32Mef.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0xd2c22f51), c.final());
+}
+
+test "CRC-32/MPEG-2" {
+ const Crc32Mpeg2 = catalog.Crc32Mpeg2;
+
+ try testing.expectEqual(@as(u32, 0x0376e6e7), Crc32Mpeg2.hash("123456789"));
+
+ var c = Crc32Mpeg2.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0x0376e6e7), c.final());
+}
+
+test "CRC-32/XFER" {
+ const Crc32Xfer = catalog.Crc32Xfer;
+
+ try testing.expectEqual(@as(u32, 0xbd0be338), Crc32Xfer.hash("123456789"));
+
+ var c = Crc32Xfer.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u32, 0xbd0be338), c.final());
+}
+
+test "CRC-40/GSM" {
+ const Crc40Gsm = catalog.Crc40Gsm;
+
+ try testing.expectEqual(@as(u40, 0xd4164fc646), Crc40Gsm.hash("123456789"));
+
+ var c = Crc40Gsm.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u40, 0xd4164fc646), c.final());
+}
+
+test "CRC-64/ECMA-182" {
+ const Crc64Ecma182 = catalog.Crc64Ecma182;
+
+ try testing.expectEqual(@as(u64, 0x6c40df5f0b497347), Crc64Ecma182.hash("123456789"));
+
+ var c = Crc64Ecma182.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0x6c40df5f0b497347), c.final());
+}
+
+test "CRC-64/GO-ISO" {
+ const Crc64GoIso = catalog.Crc64GoIso;
+
+ try testing.expectEqual(@as(u64, 0xb90956c775a41001), Crc64GoIso.hash("123456789"));
+
+ var c = Crc64GoIso.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0xb90956c775a41001), c.final());
+}
+
+test "CRC-64/MS" {
+ const Crc64Ms = catalog.Crc64Ms;
+
+ try testing.expectEqual(@as(u64, 0x75d4b74f024eceea), Crc64Ms.hash("123456789"));
+
+ var c = Crc64Ms.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0x75d4b74f024eceea), c.final());
+}
+
+test "CRC-64/REDIS" {
+ const Crc64Redis = catalog.Crc64Redis;
+
+ try testing.expectEqual(@as(u64, 0xe9c6d914c4b8d9ca), Crc64Redis.hash("123456789"));
+
+ var c = Crc64Redis.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0xe9c6d914c4b8d9ca), c.final());
+}
+
+test "CRC-64/WE" {
+ const Crc64We = catalog.Crc64We;
+
+ try testing.expectEqual(@as(u64, 0x62ec59e3f1a4f00a), Crc64We.hash("123456789"));
+
+ var c = Crc64We.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0x62ec59e3f1a4f00a), c.final());
+}
+
+test "CRC-64/XZ" {
+ const Crc64Xz = catalog.Crc64Xz;
+
+ try testing.expectEqual(@as(u64, 0x995dc9bbdf1939fa), Crc64Xz.hash("123456789"));
+
+ var c = Crc64Xz.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u64, 0x995dc9bbdf1939fa), c.final());
+}
+
+test "CRC-82/DARC" {
+ const Crc82Darc = catalog.Crc82Darc;
+
+ try testing.expectEqual(@as(u82, 0x09ea83f625023801fd612), Crc82Darc.hash("123456789"));
+
+ var c = Crc82Darc.init();
+ c.update("1234");
+ c.update("56789");
+ try testing.expectEqual(@as(u82, 0x09ea83f625023801fd612), c.final());
+}
diff --git a/lib/std/os.zig b/lib/std/os.zig
index 4339d2fe6b..b71b17243d 100644
--- a/lib/std/os.zig
+++ b/lib/std/os.zig
@@ -641,6 +641,9 @@ pub const ReadError = error{
ConnectionTimedOut,
NotOpenForReading,
+ // Windows only
+ NetNameDeleted,
+
/// This error occurs when no global event loop is configured,
/// and reading from the file descriptor would block.
WouldBlock,
diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig
index ee86bdde12..394936e709 100644
--- a/lib/std/os/windows.zig
+++ b/lib/std/os/windows.zig
@@ -435,8 +435,9 @@ pub fn FindClose(hFindFile: HANDLE) void {
}
pub const ReadFileError = error{
- OperationAborted,
BrokenPipe,
+ NetNameDeleted,
+ OperationAborted,
Unexpected,
};
@@ -475,6 +476,7 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.Mo
.IO_PENDING => unreachable,
.OPERATION_ABORTED => return error.OperationAborted,
.BROKEN_PIPE => return error.BrokenPipe,
+ .NETNAME_DELETED => return error.NetNameDeleted,
.HANDLE_EOF => return @as(usize, bytes_transferred),
else => |err| return unexpectedError(err),
}
@@ -506,9 +508,11 @@ pub fn ReadFile(in_hFile: HANDLE, buffer: []u8, offset: ?u64, io_mode: std.io.Mo
} else null;
if (kernel32.ReadFile(in_hFile, buffer.ptr, want_read_count, &amt_read, overlapped) == 0) {
switch (kernel32.GetLastError()) {
+ .IO_PENDING => unreachable,
.OPERATION_ABORTED => continue,
.BROKEN_PIPE => return 0,
.HANDLE_EOF => return 0,
+ .NETNAME_DELETED => return error.NetNameDeleted,
else => |err| return unexpectedError(err),
}
}
diff --git a/lib/std/zig/system/NativeTargetInfo.zig b/lib/std/zig/system/NativeTargetInfo.zig
index 1817bd98cb..7e57cdda9b 100644
--- a/lib/std/zig/system/NativeTargetInfo.zig
+++ b/lib/std/zig/system/NativeTargetInfo.zig
@@ -915,6 +915,7 @@ fn preadMin(file: fs.File, buf: []u8, offset: u64, min_read_len: usize) !usize {
error.Unseekable => return error.UnableToReadElfFile,
error.ConnectionResetByPeer => return error.UnableToReadElfFile,
error.ConnectionTimedOut => return error.UnableToReadElfFile,
+ error.NetNameDeleted => return error.UnableToReadElfFile,
error.Unexpected => return error.Unexpected,
error.InputOutput => return error.FileSystem,
error.AccessDenied => return error.Unexpected,
diff --git a/src/Compilation.zig b/src/Compilation.zig
index b0af925e29..09c6e1c686 100644
--- a/src/Compilation.zig
+++ b/src/Compilation.zig
@@ -639,14 +639,6 @@ pub const AllErrors = struct {
note_i += 1;
}
}
- if (module_err_msg.src_loc.lazy == .entire_file) {
- try errors.append(.{
- .plain = .{
- .msg = try allocator.dupe(u8, module_err_msg.msg),
- },
- });
- return;
- }
const reference_trace = try allocator.alloc(Message, module_err_msg.reference_trace.len);
for (reference_trace) |*reference, i| {
@@ -683,7 +675,7 @@ pub const AllErrors = struct {
.column = @intCast(u32, err_loc.column),
.notes = notes_buf[0..note_i],
.reference_trace = reference_trace,
- .source_line = try allocator.dupe(u8, err_loc.source_line),
+ .source_line = if (module_err_msg.src_loc.lazy == .entire_file) null else try allocator.dupe(u8, err_loc.source_line),
},
});
}
@@ -1610,6 +1602,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const builtin_pkg = try Package.createWithDir(
gpa,
+ "builtin",
zig_cache_artifact_directory,
null,
"builtin.zig",
@@ -1618,6 +1611,7 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
const std_pkg = try Package.createWithDir(
gpa,
+ "std",
options.zig_lib_directory,
"std",
"std.zig",
@@ -1625,11 +1619,14 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
errdefer std_pkg.destroy(gpa);
const root_pkg = if (options.is_test) root_pkg: {
+ // TODO: we currently have two packages named 'root' here, which is weird. This
+ // should be changed as part of the resolution of #12201
const test_pkg = if (options.test_runner_path) |test_runner|
- try Package.create(gpa, null, test_runner)
+ try Package.create(gpa, "root", null, test_runner)
else
try Package.createWithDir(
gpa,
+ "root",
options.zig_lib_directory,
null,
"test_runner.zig",
@@ -1640,9 +1637,9 @@ pub fn create(gpa: Allocator, options: InitOptions) !*Compilation {
} else main_pkg;
errdefer if (options.is_test) root_pkg.destroy(gpa);
- try main_pkg.addAndAdopt(gpa, "builtin", builtin_pkg);
- try main_pkg.add(gpa, "root", root_pkg);
- try main_pkg.addAndAdopt(gpa, "std", std_pkg);
+ try main_pkg.addAndAdopt(gpa, builtin_pkg);
+ try main_pkg.add(gpa, root_pkg);
+ try main_pkg.addAndAdopt(gpa, std_pkg);
const main_pkg_is_std = m: {
const std_path = try std.fs.path.resolve(arena, &[_][]const u8{
@@ -3075,6 +3072,57 @@ pub fn performAllTheWork(
}
}
+ if (comp.bin_file.options.module) |mod| {
+ for (mod.import_table.values()) |file| {
+ if (!file.multi_pkg) continue;
+ const err = err_blk: {
+ const notes = try mod.gpa.alloc(Module.ErrorMsg, file.references.items.len);
+ errdefer mod.gpa.free(notes);
+
+ for (notes) |*note, i| {
+ errdefer for (notes[0..i]) |*n| n.deinit(mod.gpa);
+ note.* = switch (file.references.items[i]) {
+ .import => |loc| try Module.ErrorMsg.init(
+ mod.gpa,
+ loc,
+ "imported from package {s}",
+ .{loc.file_scope.pkg.name},
+ ),
+ .root => |pkg| try Module.ErrorMsg.init(
+ mod.gpa,
+ .{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file },
+ "root of package {s}",
+ .{pkg.name},
+ ),
+ };
+ }
+ errdefer for (notes) |*n| n.deinit(mod.gpa);
+
+ const err = try Module.ErrorMsg.create(
+ mod.gpa,
+ .{ .file_scope = file, .parent_decl_node = 0, .lazy = .entire_file },
+ "file exists in multiple packages",
+ .{},
+ );
+ err.notes = notes;
+ break :err_blk err;
+ };
+ errdefer err.destroy(mod.gpa);
+ try mod.failed_files.putNoClobber(mod.gpa, file, err);
+ }
+
+ // Now that we've reported the errors, we need to deal with
+ // dependencies. Any file referenced by a multi_pkg file should also be
+ // marked multi_pkg and have its status set to astgen_failure, as it's
+ // ambiguous which package they should be analyzed as a part of. We need
+ // to add this flag after reporting the errors however, as otherwise
+ // we'd get an error for every single downstream file, which wouldn't be
+ // very useful.
+ for (mod.import_table.values()) |file| {
+ if (file.multi_pkg) file.recursiveMarkMultiPkg(mod);
+ }
+ }
+
{
const outdated_and_deleted_decls_frame = tracy.namedFrame("outdated_and_deleted_decls");
defer outdated_and_deleted_decls_frame.end();
@@ -3499,7 +3547,15 @@ fn workerAstGenFile(
comp.mutex.lock();
defer comp.mutex.unlock();
- break :blk mod.importFile(file, import_path) catch continue;
+ const res = mod.importFile(file, import_path) catch continue;
+ if (!res.is_pkg) {
+ res.file.addReference(mod.*, .{ .import = .{
+ .file_scope = file,
+ .parent_decl_node = 0,
+ .lazy = .{ .token_abs = item.data.token },
+ } }) catch continue;
+ }
+ break :blk res;
};
if (import_result.is_new) {
log.debug("AstGen of {s} has import '{s}'; queuing AstGen of {s}", .{
@@ -4319,11 +4375,18 @@ pub fn addCCArgs(
}
},
.macos => {
+ try argv.ensureUnusedCapacity(2);
// Pass the proper -m<os>-version-min argument for darwin.
const ver = target.os.version_range.semver.min;
- try argv.append(try std.fmt.allocPrint(arena, "-mmacos-version-min={d}.{d}.{d}", .{
+ argv.appendAssumeCapacity(try std.fmt.allocPrint(arena, "-mmacos-version-min={d}.{d}.{d}", .{
ver.major, ver.minor, ver.patch,
}));
+ // This avoids a warning that sometimes occurs when
+ // providing both a -target argument that contains a
+ // version as well as the -mmacosx-version-min argument.
+ // Zig provides the correct value in both places, so it
+ // doesn't matter which one gets overridden.
+ argv.appendAssumeCapacity("-Wno-overriding-t-option");
},
.ios, .tvos, .watchos => switch (target.cpu.arch) {
// Pass the proper -m<os>-version-min argument for darwin.
@@ -5320,6 +5383,7 @@ fn buildOutputFromZig(
var main_pkg: Package = .{
.root_src_directory = comp.zig_lib_directory,
.root_src_path = src_basename,
+ .name = "root",
};
defer main_pkg.deinitTable(comp.gpa);
const root_name = src_basename[0 .. src_basename.len - std.fs.path.extension(src_basename).len];
diff --git a/src/Module.zig b/src/Module.zig
index f2f51907cb..b17c140231 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -1943,6 +1943,10 @@ pub const File = struct {
zir: Zir,
/// Package that this file is a part of, managed externally.
pkg: *Package,
+ /// Whether this file is a part of multiple packages. This is an error condition which will be reported after AstGen.
+ multi_pkg: bool = false,
+ /// List of references to this file, used for multi-package errors.
+ references: std.ArrayListUnmanaged(Reference) = .{},
/// Used by change detection algorithm, after astgen, contains the
/// set of decls that existed in the previous ZIR but not in the new one.
@@ -1958,6 +1962,14 @@ pub const File = struct {
/// successful, this field is unloaded.
prev_zir: ?*Zir = null,
+ /// A single reference to a file.
+ const Reference = union(enum) {
+ /// The file is imported directly (i.e. not as a package) with @import.
+ import: SrcLoc,
+ /// The file is the root of a package.
+ root: *Package,
+ };
+
pub fn unload(file: *File, gpa: Allocator) void {
file.unloadTree(gpa);
file.unloadSource(gpa);
@@ -1990,6 +2002,7 @@ pub const File = struct {
log.debug("deinit File {s}", .{file.sub_file_path});
file.deleted_decls.deinit(gpa);
file.outdated_decls.deinit(gpa);
+ file.references.deinit(gpa);
if (file.root_decl.unwrap()) |root_decl| {
mod.destroyDecl(root_decl);
}
@@ -2110,6 +2123,44 @@ pub const File = struct {
else => true,
};
}
+
+ /// Add a reference to this file during AstGen.
+ pub fn addReference(file: *File, mod: Module, ref: Reference) !void {
+ try file.references.append(mod.gpa, ref);
+
+ const pkg = switch (ref) {
+ .import => |loc| loc.file_scope.pkg,
+ .root => |pkg| pkg,
+ };
+ if (pkg != file.pkg) file.multi_pkg = true;
+ }
+
+ /// Mark this file and every file referenced by it as multi_pkg and report an
+ /// astgen_failure error for them. AstGen must have completed in its entirety.
+ pub fn recursiveMarkMultiPkg(file: *File, mod: *Module) void {
+ file.multi_pkg = true;
+ file.status = .astgen_failure;
+
+ std.debug.assert(file.zir_loaded);
+ const imports_index = file.zir.extra[@enumToInt(Zir.ExtraIndex.imports)];
+ if (imports_index == 0) return;
+ const extra = file.zir.extraData(Zir.Inst.Imports, imports_index);
+
+ var import_i: u32 = 0;
+ var extra_index = extra.end;
+ while (import_i < extra.data.imports_len) : (import_i += 1) {
+ const item = file.zir.extraData(Zir.Inst.Imports.Item, extra_index);
+ extra_index = item.end;
+
+ const import_path = file.zir.nullTerminatedString(item.data.name);
+ if (mem.eql(u8, import_path, "builtin")) continue;
+
+ const res = mod.importFile(file, import_path) catch continue;
+ if (!res.is_pkg and !res.file.multi_pkg) {
+ res.file.recursiveMarkMultiPkg(mod);
+ }
+ }
+ }
};
/// Represents the contents of a file loaded with `@embedFile`.
@@ -3220,16 +3271,11 @@ pub fn deinit(mod: *Module) void {
// The callsite of `Compilation.create` owns the `main_pkg`, however
// Module owns the builtin and std packages that it adds.
if (mod.main_pkg.table.fetchRemove("builtin")) |kv| {
- gpa.free(kv.key);
kv.value.destroy(gpa);
}
if (mod.main_pkg.table.fetchRemove("std")) |kv| {
- gpa.free(kv.key);
kv.value.destroy(gpa);
}
- if (mod.main_pkg.table.fetchRemove("root")) |kv| {
- gpa.free(kv.key);
- }
if (mod.root_pkg != mod.main_pkg) {
mod.root_pkg.destroy(gpa);
}
@@ -4695,6 +4741,7 @@ pub fn declareDeclDependency(mod: *Module, depender_index: Decl.Index, dependee_
pub const ImportFileResult = struct {
file: *File,
is_new: bool,
+ is_pkg: bool,
};
pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult {
@@ -4714,6 +4761,7 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult {
if (gop.found_existing) return ImportFileResult{
.file = gop.value_ptr.*,
.is_new = false,
+ .is_pkg = true,
};
const sub_file_path = try gpa.dupe(u8, pkg.root_src_path);
@@ -4737,9 +4785,11 @@ pub fn importPkg(mod: *Module, pkg: *Package) !ImportFileResult {
.pkg = pkg,
.root_decl = .none,
};
+ try new_file.addReference(mod.*, .{ .root = pkg });
return ImportFileResult{
.file = new_file,
.is_new = true,
+ .is_pkg = true,
};
}
@@ -4780,6 +4830,7 @@ pub fn importFile(
if (gop.found_existing) return ImportFileResult{
.file = gop.value_ptr.*,
.is_new = false,
+ .is_pkg = false,
};
const new_file = try gpa.create(File);
@@ -4825,6 +4876,7 @@ pub fn importFile(
return ImportFileResult{
.file = new_file,
.is_new = true,
+ .is_pkg = false,
};
}
diff --git a/src/Package.zig b/src/Package.zig
index 23a0549aa7..f8823cc74e 100644
--- a/src/Package.zig
+++ b/src/Package.zig
@@ -24,10 +24,13 @@ table: Table = .{},
parent: ?*Package = null,
/// Whether to free `root_src_directory` on `destroy`.
root_src_directory_owned: bool = false,
+/// This information can be recovered from 'table', but it's more convenient to store on the package.
+name: []const u8,
/// Allocate a Package. No references to the slices passed are kept.
pub fn create(
gpa: Allocator,
+ name: []const u8,
/// Null indicates the current working directory
root_src_dir_path: ?[]const u8,
/// Relative to root_src_dir_path
@@ -42,6 +45,9 @@ pub fn create(
const owned_src_path = try gpa.dupe(u8, root_src_path);
errdefer gpa.free(owned_src_path);
+ const owned_name = try gpa.dupe(u8, name);
+ errdefer gpa.free(owned_name);
+
ptr.* = .{
.root_src_directory = .{
.path = owned_dir_path,
@@ -49,6 +55,7 @@ pub fn create(
},
.root_src_path = owned_src_path,
.root_src_directory_owned = true,
+ .name = owned_name,
};
return ptr;
@@ -56,6 +63,7 @@ pub fn create(
pub fn createWithDir(
gpa: Allocator,
+ name: []const u8,
directory: Compilation.Directory,
/// Relative to `directory`. If null, means `directory` is the root src dir
/// and is owned externally.
@@ -69,6 +77,9 @@ pub fn createWithDir(
const owned_src_path = try gpa.dupe(u8, root_src_path);
errdefer gpa.free(owned_src_path);
+ const owned_name = try gpa.dupe(u8, name);
+ errdefer gpa.free(owned_name);
+
if (root_src_dir_path) |p| {
const owned_dir_path = try directory.join(gpa, &[1][]const u8{p});
errdefer gpa.free(owned_dir_path);
@@ -80,12 +91,14 @@ pub fn createWithDir(
},
.root_src_directory_owned = true,
.root_src_path = owned_src_path,
+ .name = owned_name,
};
} else {
ptr.* = .{
.root_src_directory = directory,
.root_src_directory_owned = false,
.root_src_path = owned_src_path,
+ .name = owned_name,
};
}
return ptr;
@@ -95,6 +108,7 @@ pub fn createWithDir(
/// inside its table; the caller is responsible for calling destroy() on them.
pub fn destroy(pkg: *Package, gpa: Allocator) void {
gpa.free(pkg.root_src_path);
+ gpa.free(pkg.name);
if (pkg.root_src_directory_owned) {
// If root_src_directory.path is null then the handle is the cwd()
@@ -111,24 +125,18 @@ pub fn destroy(pkg: *Package, gpa: Allocator) void {
/// Only frees memory associated with the table.
pub fn deinitTable(pkg: *Package, gpa: Allocator) void {
- var it = pkg.table.keyIterator();
- while (it.next()) |key| {
- gpa.free(key.*);
- }
-
pkg.table.deinit(gpa);
}
-pub fn add(pkg: *Package, gpa: Allocator, name: []const u8, package: *Package) !void {
+pub fn add(pkg: *Package, gpa: Allocator, package: *Package) !void {
try pkg.table.ensureUnusedCapacity(gpa, 1);
- const name_dupe = try gpa.dupe(u8, name);
- pkg.table.putAssumeCapacityNoClobber(name_dupe, package);
+ pkg.table.putAssumeCapacityNoClobber(package.name, package);
}
-pub fn addAndAdopt(parent: *Package, gpa: Allocator, name: []const u8, child: *Package) !void {
+pub fn addAndAdopt(parent: *Package, gpa: Allocator, child: *Package) !void {
assert(child.parent == null); // make up your mind, who is the parent??
child.parent = parent;
- return parent.add(gpa, name, child);
+ return parent.add(gpa, child);
}
pub const build_zig_basename = "build.zig";
@@ -237,7 +245,7 @@ pub fn fetchAndAddDependencies(
sub_prefix,
);
- try addAndAdopt(pkg, gpa, fqn, sub_pkg);
+ try addAndAdopt(pkg, gpa, sub_pkg);
try dependencies_source.writer().print(" pub const {s} = @import(\"{}\");\n", .{
std.zig.fmtId(fqn), std.zig.fmtEscapes(fqn),
@@ -249,6 +257,7 @@ pub fn fetchAndAddDependencies(
pub fn createFilePkg(
gpa: Allocator,
+ name: []const u8,
cache_directory: Compilation.Directory,
basename: []const u8,
contents: []const u8,
@@ -269,7 +278,7 @@ pub fn createFilePkg(
const o_dir_sub_path = "o" ++ fs.path.sep_str ++ hex_digest;
try renameTmpIntoCache(cache_directory.handle, tmp_dir_sub_path, o_dir_sub_path);
- return createWithDir(gpa, cache_directory, o_dir_sub_path, basename);
+ return createWithDir(gpa, name, cache_directory, o_dir_sub_path, basename);
}
fn fetchAndUnpack(
@@ -312,6 +321,9 @@ fn fetchAndUnpack(
const owned_src_path = try gpa.dupe(u8, build_zig_basename);
errdefer gpa.free(owned_src_path);
+ const owned_name = try gpa.dupe(u8, fqn);
+ errdefer gpa.free(owned_name);
+
const build_root = try global_cache_directory.join(gpa, &.{pkg_dir_sub_path});
errdefer gpa.free(build_root);
@@ -326,6 +338,7 @@ fn fetchAndUnpack(
},
.root_src_directory_owned = true,
.root_src_path = owned_src_path,
+ .name = owned_name,
};
return ptr;
@@ -414,7 +427,7 @@ fn fetchAndUnpack(
std.zig.fmtId(fqn), std.zig.fmtEscapes(build_root),
});
- return createWithDir(gpa, global_cache_directory, pkg_dir_sub_path, build_zig_basename);
+ return createWithDir(gpa, fqn, global_cache_directory, pkg_dir_sub_path, build_zig_basename);
}
fn reportError(
diff --git a/src/Sema.zig b/src/Sema.zig
index 124af6c131..2e57de2406 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -5211,6 +5211,7 @@ fn zirCImport(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileEr
}
const c_import_pkg = Package.create(
sema.gpa,
+ "c_import", // TODO: should we make this unique?
null,
c_import_res.out_zig_path,
) catch |err| switch (err) {
@@ -11663,20 +11664,7 @@ fn zirImport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.
},
error.PackageNotFound => {
const cur_pkg = block.getFileScope().pkg;
- const parent = if (cur_pkg == sema.mod.main_pkg or cur_pkg == sema.mod.root_pkg)
- "root"
- else if (cur_pkg.parent) |parent| blk: {
- var it = parent.table.iterator();
- while (it.next()) |pkg| {
- if (pkg.value_ptr.* == cur_pkg) {
- break :blk pkg.key_ptr.*;
- }
- }
- unreachable;
- } else {
- return sema.fail(block, operand_src, "no package named '{s}' available", .{operand});
- };
- return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, parent });
+ return sema.fail(block, operand_src, "no package named '{s}' available within package '{s}'", .{ operand, cur_pkg.name });
},
else => {
// TODO: these errors are file system errors; make sure an update() will
diff --git a/src/link.zig b/src/link.zig
index 2317525827..976debb72b 100644
--- a/src/link.zig
+++ b/src/link.zig
@@ -489,6 +489,7 @@ pub const File = struct {
NameTooLong,
CurrentWorkingDirectoryUnlinked,
LockViolation,
+ NetNameDeleted,
};
/// Called from within the CodeGen to lower a local variable instantion as an unnamed
diff --git a/src/main.zig b/src/main.zig
index 9455bc328a..fdc761ac92 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -857,6 +857,7 @@ fn buildOutputType(
var pkg_tree_root: Package = .{
.root_src_directory = .{ .path = null, .handle = fs.cwd() },
.root_src_path = &[0]u8{},
+ .name = &[0]u8{},
};
defer freePkgTree(gpa, &pkg_tree_root, false);
var cur_pkg: *Package = &pkg_tree_root;
@@ -947,6 +948,7 @@ fn buildOutputType(
const new_cur_pkg = Package.create(
gpa,
+ pkg_name,
fs.path.dirname(pkg_path),
fs.path.basename(pkg_path),
) catch |err| {
@@ -958,7 +960,7 @@ fn buildOutputType(
} else if (cur_pkg.table.get(pkg_name)) |prev| {
fatal("unable to add package '{s}' -> '{s}': already exists as '{s}", .{ pkg_name, pkg_path, prev.root_src_path });
}
- try cur_pkg.addAndAdopt(gpa, pkg_name, new_cur_pkg);
+ try cur_pkg.addAndAdopt(gpa, new_cur_pkg);
cur_pkg = new_cur_pkg;
} else if (mem.eql(u8, arg, "--pkg-end")) {
cur_pkg = cur_pkg.parent orelse
@@ -2841,14 +2843,14 @@ fn buildOutputType(
if (main_pkg_path) |unresolved_main_pkg_path| {
const p = try introspect.resolvePath(arena, unresolved_main_pkg_path);
if (p.len == 0) {
- break :blk try Package.create(gpa, null, src_path);
+ break :blk try Package.create(gpa, "root", null, src_path);
} else {
const rel_src_path = try fs.path.relative(arena, p, src_path);
- break :blk try Package.create(gpa, p, rel_src_path);
+ break :blk try Package.create(gpa, "root", p, rel_src_path);
}
} else {
const root_src_dir_path = fs.path.dirname(src_path);
- break :blk Package.create(gpa, root_src_dir_path, fs.path.basename(src_path)) catch |err| {
+ break :blk Package.create(gpa, "root", root_src_dir_path, fs.path.basename(src_path)) catch |err| {
if (root_src_dir_path) |p| {
fatal("unable to open '{s}': {s}", .{ p, @errorName(err) });
} else {
@@ -4093,6 +4095,7 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
var main_pkg: Package = .{
.root_src_directory = zig_lib_directory,
.root_src_path = "build_runner.zig",
+ .name = "root",
};
if (!build_options.omit_pkg_fetching_code) {
@@ -4133,20 +4136,22 @@ pub fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !voi
const deps_pkg = try Package.createFilePkg(
gpa,
+ "@dependencies",
local_cache_directory,
"dependencies.zig",
dependencies_source.items,
);
mem.swap(Package.Table, &main_pkg.table, &deps_pkg.table);
- try main_pkg.addAndAdopt(gpa, "@dependencies", deps_pkg);
+ try main_pkg.addAndAdopt(gpa, deps_pkg);
}
var build_pkg: Package = .{
.root_src_directory = build_directory,
.root_src_path = build_zig_basename,
+ .name = "@build",
};
- try main_pkg.addAndAdopt(gpa, "@build", &build_pkg);
+ try main_pkg.addAndAdopt(gpa, &build_pkg);
const comp = Compilation.create(gpa, .{
.zig_lib_directory = zig_lib_directory,
@@ -4381,7 +4386,7 @@ pub fn cmdFmt(gpa: Allocator, arena: Allocator, args: []const []const u8) !void
.root_decl = .none,
};
- file.pkg = try Package.create(gpa, null, file.sub_file_path);
+ file.pkg = try Package.create(gpa, "root", null, file.sub_file_path);
defer file.pkg.destroy(gpa);
file.zir = try AstGen.generate(gpa, file.tree);
@@ -4482,6 +4487,7 @@ const FmtError = error{
UnsupportedEncoding,
ConnectionResetByPeer,
LockViolation,
+ NetNameDeleted,
} || fs.File.OpenError;
fn fmtPath(fmt: *Fmt, file_path: []const u8, check_mode: bool, dir: fs.Dir, sub_path: []const u8) FmtError!void {
@@ -4591,7 +4597,7 @@ fn fmtPathFile(
.root_decl = .none,
};
- file.pkg = try Package.create(fmt.gpa, null, file.sub_file_path);
+ file.pkg = try Package.create(fmt.gpa, "root", null, file.sub_file_path);
defer file.pkg.destroy(fmt.gpa);
if (stat.size > max_src_size)
@@ -5303,7 +5309,7 @@ pub fn cmdAstCheck(
file.stat.size = source.len;
}
- file.pkg = try Package.create(gpa, null, file.sub_file_path);
+ file.pkg = try Package.create(gpa, "root", null, file.sub_file_path);
defer file.pkg.destroy(gpa);
file.tree = try std.zig.parse(gpa, file.source);
@@ -5422,7 +5428,7 @@ pub fn cmdChangelist(
.root_decl = .none,
};
- file.pkg = try Package.create(gpa, null, file.sub_file_path);
+ file.pkg = try Package.create(gpa, "root", null, file.sub_file_path);
defer file.pkg.destroy(gpa);
const source = try arena.allocSentinel(u8, @intCast(usize, stat.size), 0);
diff --git a/src/test.zig b/src/test.zig
index 08a62b891f..b25a6c1e78 100644
--- a/src/test.zig
+++ b/src/test.zig
@@ -1497,6 +1497,7 @@ pub const TestContext = struct {
var main_pkg: Package = .{
.root_src_directory = .{ .path = tmp_dir_path, .handle = tmp.dir },
.root_src_path = tmp_src_path,
+ .name = "root",
};
defer main_pkg.table.deinit(allocator);
diff --git a/tools/crc/catalog.txt b/tools/crc/catalog.txt
new file mode 100644
index 0000000000..a437141447
--- /dev/null
+++ b/tools/crc/catalog.txt
@@ -0,0 +1,113 @@
+# https://reveng.sourceforge.io/crc-catalogue/all.htm
+width=3 poly=0x3 init=0x0 refin=false refout=false xorout=0x7 check=0x4 residue=0x2 name="CRC-3/GSM"
+width=3 poly=0x3 init=0x7 refin=true refout=true xorout=0x0 check=0x6 residue=0x0 name="CRC-3/ROHC"
+width=4 poly=0x3 init=0x0 refin=true refout=true xorout=0x0 check=0x7 residue=0x0 name="CRC-4/G-704"
+width=4 poly=0x3 init=0xf refin=false refout=false xorout=0xf check=0xb residue=0x2 name="CRC-4/INTERLAKEN"
+width=5 poly=0x09 init=0x09 refin=false refout=false xorout=0x00 check=0x00 residue=0x00 name="CRC-5/EPC-C1G2"
+width=5 poly=0x15 init=0x00 refin=true refout=true xorout=0x00 check=0x07 residue=0x00 name="CRC-5/G-704"
+width=5 poly=0x05 init=0x1f refin=true refout=true xorout=0x1f check=0x19 residue=0x06 name="CRC-5/USB"
+width=6 poly=0x27 init=0x3f refin=false refout=false xorout=0x00 check=0x0d residue=0x00 name="CRC-6/CDMA2000-A"
+width=6 poly=0x07 init=0x3f refin=false refout=false xorout=0x00 check=0x3b residue=0x00 name="CRC-6/CDMA2000-B"
+width=6 poly=0x19 init=0x00 refin=true refout=true xorout=0x00 check=0x26 residue=0x00 name="CRC-6/DARC"
+width=6 poly=0x03 init=0x00 refin=true refout=true xorout=0x00 check=0x06 residue=0x00 name="CRC-6/G-704"
+width=6 poly=0x2f init=0x00 refin=false refout=false xorout=0x3f check=0x13 residue=0x3a name="CRC-6/GSM"
+width=7 poly=0x09 init=0x00 refin=false refout=false xorout=0x00 check=0x75 residue=0x00 name="CRC-7/MMC"
+width=7 poly=0x4f init=0x7f refin=true refout=true xorout=0x00 check=0x53 residue=0x00 name="CRC-7/ROHC"
+width=7 poly=0x45 init=0x00 refin=false refout=false xorout=0x00 check=0x61 residue=0x00 name="CRC-7/UMTS"
+width=8 poly=0x2f init=0xff refin=false refout=false xorout=0xff check=0xdf residue=0x42 name="CRC-8/AUTOSAR"
+width=8 poly=0xa7 init=0x00 refin=true refout=true xorout=0x00 check=0x26 residue=0x00 name="CRC-8/BLUETOOTH"
+width=8 poly=0x9b init=0xff refin=false refout=false xorout=0x00 check=0xda residue=0x00 name="CRC-8/CDMA2000"
+width=8 poly=0x39 init=0x00 refin=true refout=true xorout=0x00 check=0x15 residue=0x00 name="CRC-8/DARC"
+width=8 poly=0xd5 init=0x00 refin=false refout=false xorout=0x00 check=0xbc residue=0x00 name="CRC-8/DVB-S2"
+width=8 poly=0x1d init=0x00 refin=false refout=false xorout=0x00 check=0x37 residue=0x00 name="CRC-8/GSM-A"
+width=8 poly=0x49 init=0x00 refin=false refout=false xorout=0xff check=0x94 residue=0x53 name="CRC-8/GSM-B"
+width=8 poly=0x1d init=0xff refin=false refout=false xorout=0x00 check=0xb4 residue=0x00 name="CRC-8/HITAG"
+width=8 poly=0x07 init=0x00 refin=false refout=false xorout=0x55 check=0xa1 residue=0xac name="CRC-8/I-432-1"
+width=8 poly=0x1d init=0xfd refin=false refout=false xorout=0x00 check=0x7e residue=0x00 name="CRC-8/I-CODE"
+width=8 poly=0x9b init=0x00 refin=false refout=false xorout=0x00 check=0xea residue=0x00 name="CRC-8/LTE"
+width=8 poly=0x31 init=0x00 refin=true refout=true xorout=0x00 check=0xa1 residue=0x00 name="CRC-8/MAXIM-DOW"
+width=8 poly=0x1d init=0xc7 refin=false refout=false xorout=0x00 check=0x99 residue=0x00 name="CRC-8/MIFARE-MAD"
+width=8 poly=0x31 init=0xff refin=false refout=false xorout=0x00 check=0xf7 residue=0x00 name="CRC-8/NRSC-5"
+width=8 poly=0x2f init=0x00 refin=false refout=false xorout=0x00 check=0x3e residue=0x00 name="CRC-8/OPENSAFETY"
+width=8 poly=0x07 init=0xff refin=true refout=true xorout=0x00 check=0xd0 residue=0x00 name="CRC-8/ROHC"
+width=8 poly=0x1d init=0xff refin=false refout=false xorout=0xff check=0x4b residue=0xc4 name="CRC-8/SAE-J1850"
+width=8 poly=0x07 init=0x00 refin=false refout=false xorout=0x00 check=0xf4 residue=0x00 name="CRC-8/SMBUS"
+width=8 poly=0x1d init=0xff refin=true refout=true xorout=0x00 check=0x97 residue=0x00 name="CRC-8/TECH-3250"
+width=8 poly=0x9b init=0x00 refin=true refout=true xorout=0x00 check=0x25 residue=0x00 name="CRC-8/WCDMA"
+width=10 poly=0x233 init=0x000 refin=false refout=false xorout=0x000 check=0x199 residue=0x000 name="CRC-10/ATM"
+width=10 poly=0x3d9 init=0x3ff refin=false refout=false xorout=0x000 check=0x233 residue=0x000 name="CRC-10/CDMA2000"
+width=10 poly=0x175 init=0x000 refin=false refout=false xorout=0x3ff check=0x12a residue=0x0c6 name="CRC-10/GSM"
+width=11 poly=0x385 init=0x01a refin=false refout=false xorout=0x000 check=0x5a3 residue=0x000 name="CRC-11/FLEXRAY"
+width=11 poly=0x307 init=0x000 refin=false refout=false xorout=0x000 check=0x061 residue=0x000 name="CRC-11/UMTS"
+width=12 poly=0xf13 init=0xfff refin=false refout=false xorout=0x000 check=0xd4d residue=0x000 name="CRC-12/CDMA2000"
+width=12 poly=0x80f init=0x000 refin=false refout=false xorout=0x000 check=0xf5b residue=0x000 name="CRC-12/DECT"
+width=12 poly=0xd31 init=0x000 refin=false refout=false xorout=0xfff check=0xb34 residue=0x178 name="CRC-12/GSM"
+width=12 poly=0x80f init=0x000 refin=false refout=true xorout=0x000 check=0xdaf residue=0x000 name="CRC-12/UMTS"
+width=13 poly=0x1cf5 init=0x0000 refin=false refout=false xorout=0x0000 check=0x04fa residue=0x0000 name="CRC-13/BBC"
+width=14 poly=0x0805 init=0x0000 refin=true refout=true xorout=0x0000 check=0x082d residue=0x0000 name="CRC-14/DARC"
+width=14 poly=0x202d init=0x0000 refin=false refout=false xorout=0x3fff check=0x30ae residue=0x031e name="CRC-14/GSM"
+width=15 poly=0x4599 init=0x0000 refin=false refout=false xorout=0x0000 check=0x059e residue=0x0000 name="CRC-15/CAN"
+width=15 poly=0x6815 init=0x0000 refin=false refout=false xorout=0x0001 check=0x2566 residue=0x6815 name="CRC-15/MPT1327"
+width=16 poly=0x8005 init=0x0000 refin=true refout=true xorout=0x0000 check=0xbb3d residue=0x0000 name="CRC-16/ARC"
+width=16 poly=0xc867 init=0xffff refin=false refout=false xorout=0x0000 check=0x4c06 residue=0x0000 name="CRC-16/CDMA2000"
+width=16 poly=0x8005 init=0xffff refin=false refout=false xorout=0x0000 check=0xaee7 residue=0x0000 name="CRC-16/CMS"
+width=16 poly=0x8005 init=0x800d refin=false refout=false xorout=0x0000 check=0x9ecf residue=0x0000 name="CRC-16/DDS-110"
+width=16 poly=0x0589 init=0x0000 refin=false refout=false xorout=0x0001 check=0x007e residue=0x0589 name="CRC-16/DECT-R"
+width=16 poly=0x0589 init=0x0000 refin=false refout=false xorout=0x0000 check=0x007f residue=0x0000 name="CRC-16/DECT-X"
+width=16 poly=0x3d65 init=0x0000 refin=true refout=true xorout=0xffff check=0xea82 residue=0x66c5 name="CRC-16/DNP"
+width=16 poly=0x3d65 init=0x0000 refin=false refout=false xorout=0xffff check=0xc2b7 residue=0xa366 name="CRC-16/EN-13757"
+width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0xffff check=0xd64e residue=0x1d0f name="CRC-16/GENIBUS"
+width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0xffff check=0xce3c residue=0x1d0f name="CRC-16/GSM"
+width=16 poly=0x1021 init=0xffff refin=false refout=false xorout=0x0000 check=0x29b1 residue=0x0000 name="CRC-16/IBM-3740"
+width=16 poly=0x1021 init=0xffff refin=true refout=true xorout=0xffff check=0x906e residue=0xf0b8 name="CRC-16/IBM-SDLC"
+width=16 poly=0x1021 init=0xc6c6 refin=true refout=true xorout=0x0000 check=0xbf05 residue=0x0000 name="CRC-16/ISO-IEC-14443-3-A"
+width=16 poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 check=0x2189 residue=0x0000 name="CRC-16/KERMIT"
+width=16 poly=0x6f63 init=0x0000 refin=false refout=false xorout=0x0000 check=0xbdf4 residue=0x0000 name="CRC-16/LJ1200"
+width=16 poly=0x5935 init=0xffff refin=false refout=false xorout=0x0000 check=0x772b residue=0x0000 name="CRC-16/M17"
+width=16 poly=0x8005 init=0x0000 refin=true refout=true xorout=0xffff check=0x44c2 residue=0xb001 name="CRC-16/MAXIM-DOW"
+width=16 poly=0x1021 init=0xffff refin=true refout=true xorout=0x0000 check=0x6f91 residue=0x0000 name="CRC-16/MCRF4XX"
+width=16 poly=0x8005 init=0xffff refin=true refout=true xorout=0x0000 check=0x4b37 residue=0x0000 name="CRC-16/MODBUS"
+width=16 poly=0x080b init=0xffff refin=true refout=true xorout=0x0000 check=0xa066 residue=0x0000 name="CRC-16/NRSC-5"
+width=16 poly=0x5935 init=0x0000 refin=false refout=false xorout=0x0000 check=0x5d38 residue=0x0000 name="CRC-16/OPENSAFETY-A"
+width=16 poly=0x755b init=0x0000 refin=false refout=false xorout=0x0000 check=0x20fe residue=0x0000 name="CRC-16/OPENSAFETY-B"
+width=16 poly=0x1dcf init=0xffff refin=false refout=false xorout=0xffff check=0xa819 residue=0xe394 name="CRC-16/PROFIBUS"
+width=16 poly=0x1021 init=0xb2aa refin=true refout=true xorout=0x0000 check=0x63d0 residue=0x0000 name="CRC-16/RIELLO"
+width=16 poly=0x1021 init=0x1d0f refin=false refout=false xorout=0x0000 check=0xe5cc residue=0x0000 name="CRC-16/SPI-FUJITSU"
+width=16 poly=0x8bb7 init=0x0000 refin=false refout=false xorout=0x0000 check=0xd0db residue=0x0000 name="CRC-16/T10-DIF"
+width=16 poly=0xa097 init=0x0000 refin=false refout=false xorout=0x0000 check=0x0fb3 residue=0x0000 name="CRC-16/TELEDISK"
+width=16 poly=0x1021 init=0x89ec refin=true refout=true xorout=0x0000 check=0x26b1 residue=0x0000 name="CRC-16/TMS37157"
+width=16 poly=0x8005 init=0x0000 refin=false refout=false xorout=0x0000 check=0xfee8 residue=0x0000 name="CRC-16/UMTS"
+width=16 poly=0x8005 init=0xffff refin=true refout=true xorout=0xffff check=0xb4c8 residue=0xb001 name="CRC-16/USB"
+width=16 poly=0x1021 init=0x0000 refin=false refout=false xorout=0x0000 check=0x31c3 residue=0x0000 name="CRC-16/XMODEM"
+width=17 poly=0x1685b init=0x00000 refin=false refout=false xorout=0x00000 check=0x04f03 residue=0x00000 name="CRC-17/CAN-FD"
+width=21 poly=0x102899 init=0x000000 refin=false refout=false xorout=0x000000 check=0x0ed841 residue=0x000000 name="CRC-21/CAN-FD"
+width=24 poly=0x00065b init=0x555555 refin=true refout=true xorout=0x000000 check=0xc25a56 residue=0x000000 name="CRC-24/BLE"
+width=24 poly=0x5d6dcb init=0xfedcba refin=false refout=false xorout=0x000000 check=0x7979bd residue=0x000000 name="CRC-24/FLEXRAY-A"
+width=24 poly=0x5d6dcb init=0xabcdef refin=false refout=false xorout=0x000000 check=0x1f23b8 residue=0x000000 name="CRC-24/FLEXRAY-B"
+width=24 poly=0x328b63 init=0xffffff refin=false refout=false xorout=0xffffff check=0xb4f3e6 residue=0x144e63 name="CRC-24/INTERLAKEN"
+width=24 poly=0x864cfb init=0x000000 refin=false refout=false xorout=0x000000 check=0xcde703 residue=0x000000 name="CRC-24/LTE-A"
+width=24 poly=0x800063 init=0x000000 refin=false refout=false xorout=0x000000 check=0x23ef52 residue=0x000000 name="CRC-24/LTE-B"
+width=24 poly=0x864cfb init=0xb704ce refin=false refout=false xorout=0x000000 check=0x21cf02 residue=0x000000 name="CRC-24/OPENPGP"
+width=24 poly=0x800063 init=0xffffff refin=false refout=false xorout=0xffffff check=0x200fa5 residue=0x800fe3 name="CRC-24/OS-9"
+width=30 poly=0x2030b9c7 init=0x3fffffff refin=false refout=false xorout=0x3fffffff check=0x04c34abf residue=0x34efa55a name="CRC-30/CDMA"
+width=31 poly=0x04c11db7 init=0x7fffffff refin=false refout=false xorout=0x7fffffff check=0x0ce9e46c residue=0x4eaf26f1 name="CRC-31/PHILIPS"
+width=32 poly=0x814141ab init=0x00000000 refin=false refout=false xorout=0x00000000 check=0x3010bf7f residue=0x00000000 name="CRC-32/AIXM"
+width=32 poly=0xf4acfb13 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0x1697d06a residue=0x904cddbf name="CRC-32/AUTOSAR"
+width=32 poly=0xa833982b init=0xffffffff refin=true refout=true xorout=0xffffffff check=0x87315576 residue=0x45270551 name="CRC-32/BASE91-D"
+width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0xffffffff check=0xfc891918 residue=0xc704dd7b name="CRC-32/BZIP2"
+width=32 poly=0x8001801b init=0x00000000 refin=true refout=true xorout=0x00000000 check=0x6ec2edc4 residue=0x00000000 name="CRC-32/CD-ROM-EDC"
+width=32 poly=0x04c11db7 init=0x00000000 refin=false refout=false xorout=0xffffffff check=0x765e7680 residue=0xc704dd7b name="CRC-32/CKSUM"
+width=32 poly=0x1edc6f41 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xe3069283 residue=0xb798b438 name="CRC-32/ISCSI"
+width=32 poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0xffffffff check=0xcbf43926 residue=0xdebb20e3 name="CRC-32/ISO-HDLC"
+width=32 poly=0x04c11db7 init=0xffffffff refin=true refout=true xorout=0x00000000 check=0x340bc6d9 residue=0x00000000 name="CRC-32/JAMCRC"
+width=32 poly=0x741b8cd7 init=0xffffffff refin=true refout=true xorout=0x00000000 check=0xd2c22f51 residue=0x00000000 name="CRC-32/MEF"
+width=32 poly=0x04c11db7 init=0xffffffff refin=false refout=false xorout=0x00000000 check=0x0376e6e7 residue=0x00000000 name="CRC-32/MPEG-2"
+width=32 poly=0x000000af init=0x00000000 refin=false refout=false xorout=0x00000000 check=0xbd0be338 residue=0x00000000 name="CRC-32/XFER"
+width=40 poly=0x0004820009 init=0x0000000000 refin=false refout=false xorout=0xffffffffff check=0xd4164fc646 residue=0xc4ff8071ff name="CRC-40/GSM"
+width=64 poly=0x42f0e1eba9ea3693 init=0x0000000000000000 refin=false refout=false xorout=0x0000000000000000 check=0x6c40df5f0b497347 residue=0x0000000000000000 name="CRC-64/ECMA-182"
+width=64 poly=0x000000000000001b init=0xffffffffffffffff refin=true refout=true xorout=0xffffffffffffffff check=0xb90956c775a41001 residue=0x5300000000000000 name="CRC-64/GO-ISO"
+width=64 poly=0x259c84cba6426349 init=0xffffffffffffffff refin=true refout=true xorout=0x0000000000000000 check=0x75d4b74f024eceea residue=0x0000000000000000 name="CRC-64/MS"
+width=64 poly=0xad93d23594c935a9 init=0x0000000000000000 refin=true refout=true xorout=0x0000000000000000 check=0xe9c6d914c4b8d9ca residue=0x0000000000000000 name="CRC-64/REDIS"
+width=64 poly=0x42f0e1eba9ea3693 init=0xffffffffffffffff refin=false refout=false xorout=0xffffffffffffffff check=0x62ec59e3f1a4f00a residue=0xfcacbebd5931a992 name="CRC-64/WE"
+width=64 poly=0x42f0e1eba9ea3693 init=0xffffffffffffffff refin=true refout=true xorout=0xffffffffffffffff check=0x995dc9bbdf1939fa residue=0x49958c9abd7d353f name="CRC-64/XZ"
+width=82 poly=0x0308c0111011401440411 init=0x000000000000000000000 refin=true refout=true xorout=0x000000000000000000000 check=0x09ea83f625023801fd612 residue=0x000000000000000000000 name="CRC-82/DARC"
diff --git a/tools/update_crc_catalog.zig b/tools/update_crc_catalog.zig
new file mode 100644
index 0000000000..8182e8d810
--- /dev/null
+++ b/tools/update_crc_catalog.zig
@@ -0,0 +1,169 @@
+const std = @import("std");
+const fs = std.fs;
+const mem = std.mem;
+const ascii = std.ascii;
+
+const catalog_txt = @embedFile("crc/catalog.txt");
+
+pub fn main() anyerror!void {
+ var arena_state = std.heap.ArenaAllocator.init(std.heap.page_allocator);
+ defer arena_state.deinit();
+ const arena = arena_state.allocator();
+
+ const args = try std.process.argsAlloc(arena);
+ if (args.len <= 1) {
+ usageAndExit(std.io.getStdErr(), args[0], 1);
+ }
+
+ const zig_src_root = args[1];
+ if (mem.startsWith(u8, zig_src_root, "-")) {
+ usageAndExit(std.io.getStdErr(), args[0], 1);
+ }
+
+ var zig_src_dir = try fs.cwd().openDir(zig_src_root, .{});
+ defer zig_src_dir.close();
+
+ const target_sub_path = try fs.path.join(arena, &.{ "lib", "std", "hash", "crc" });
+ var target_dir = try zig_src_dir.makeOpenPath(target_sub_path, .{});
+ defer target_dir.close();
+
+ var zig_code_file = try target_dir.createFile("catalog.zig", .{});
+ defer zig_code_file.close();
+
+ var cbw = std.io.bufferedWriter(zig_code_file.writer());
+ defer cbw.flush() catch unreachable;
+ const code_writer = cbw.writer();
+
+ try code_writer.writeAll(
+ \\//! This file is auto-generated by tools/update_crc_catalog.zig.
+ \\
+ \\const Crc = @import("../crc.zig").Crc;
+ \\
+ \\test {
+ \\ _ = @import("catalog_test.zig");
+ \\}
+ \\
+ );
+
+ var zig_test_file = try target_dir.createFile("catalog_test.zig", .{});
+ defer zig_test_file.close();
+
+ var tbw = std.io.bufferedWriter(zig_test_file.writer());
+ defer tbw.flush() catch unreachable;
+ const test_writer = tbw.writer();
+
+ try test_writer.writeAll(
+ \\//! This file is auto-generated by tools/update_crc_catalog.zig.
+ \\
+ \\const std = @import("../../std.zig");
+ \\const testing = std.testing;
+ \\const catalog = @import("catalog.zig");
+ \\
+ );
+
+ var stream = std.io.fixedBufferStream(catalog_txt);
+ const reader = stream.reader();
+
+ while (try reader.readUntilDelimiterOrEofAlloc(arena, '\n', std.math.maxInt(usize))) |line| {
+ if (line.len == 0 or line[0] == '#')
+ continue;
+
+ var width: []const u8 = undefined;
+ var poly: []const u8 = undefined;
+ var init: []const u8 = undefined;
+ var refin: []const u8 = undefined;
+ var refout: []const u8 = undefined;
+ var xorout: []const u8 = undefined;
+ var check: []const u8 = undefined;
+ var residue: []const u8 = undefined;
+ var name: []const u8 = undefined;
+
+ var it = mem.split(u8, line, " ");
+ while (it.next()) |property| {
+ const i = mem.indexOf(u8, property, "=").?;
+ const key = property[0..i];
+ const value = property[i + 1 ..];
+ if (mem.eql(u8, key, "width")) {
+ width = value;
+ } else if (mem.eql(u8, key, "poly")) {
+ poly = value;
+ } else if (mem.eql(u8, key, "init")) {
+ init = value;
+ } else if (mem.eql(u8, key, "refin")) {
+ refin = value;
+ } else if (mem.eql(u8, key, "refout")) {
+ refout = value;
+ } else if (mem.eql(u8, key, "xorout")) {
+ xorout = value;
+ } else if (mem.eql(u8, key, "check")) {
+ check = value;
+ } else if (mem.eql(u8, key, "residue")) {
+ residue = value;
+ } else if (mem.eql(u8, key, "name")) {
+ name = mem.trim(u8, value, "\"");
+ } else {
+ unreachable;
+ }
+ }
+
+ const snakecase = try ascii.allocLowerString(arena, name);
+ defer arena.free(snakecase);
+
+ _ = mem.replace(u8, snakecase, "-", "_", snakecase);
+ _ = mem.replace(u8, snakecase, "/", "_", snakecase);
+
+ var buf = try std.ArrayList(u8).initCapacity(arena, snakecase.len);
+ defer buf.deinit();
+
+ var prev: u8 = 0;
+ for (snakecase) |c, i| {
+ if (c == '_') {
+ // do nothing
+ } else if (i == 0) {
+ buf.appendAssumeCapacity(ascii.toUpper(c));
+ } else if (prev == '_') {
+ buf.appendAssumeCapacity(ascii.toUpper(c));
+ } else {
+ buf.appendAssumeCapacity(c);
+ }
+ prev = c;
+ }
+
+ const camelcase = buf.items;
+
+ try code_writer.writeAll(try std.fmt.allocPrint(arena,
+ \\
+ \\pub const {s} = Crc(u{s}, .{{
+ \\ .polynomial = {s},
+ \\ .initial = {s},
+ \\ .reflect_input = {s},
+ \\ .reflect_output = {s},
+ \\ .xor_output = {s},
+ \\}});
+ \\
+ , .{ camelcase, width, poly, init, refin, refout, xorout }));
+
+ try test_writer.writeAll(try std.fmt.allocPrint(arena,
+ \\
+ \\test "{0s}" {{
+ \\ const {1s} = catalog.{1s};
+ \\
+ \\ try testing.expectEqual(@as(u{2s}, {3s}), {1s}.hash("123456789"));
+ \\
+ \\ var c = {1s}.init();
+ \\ c.update("1234");
+ \\ c.update("56789");
+ \\ try testing.expectEqual(@as(u{2s}, {3s}), c.final());
+ \\}}
+ \\
+ , .{ name, camelcase, width, check }));
+ }
+}
+
+fn usageAndExit(file: fs.File, arg0: []const u8, code: u8) noreturn {
+ file.writer().print(
+ \\Usage: {s} /path/git/zig
+ \\
+ , .{arg0}) catch std.process.exit(1);
+ std.process.exit(code);
+}