mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-04-27 19:09:47 +03:00
Merge remote-tracking branch 'origin/master' into llvm10
This commit is contained in:
@@ -3,8 +3,11 @@ packages:
|
||||
- cmake
|
||||
- py27-s3cmd
|
||||
- wget
|
||||
- curl
|
||||
- jq
|
||||
secrets:
|
||||
- 6c60aaee-92e7-4e7d-812c-114817689b4d
|
||||
- dd0bd962-7664-4d3e-b0f3-41c9ee96b8b8
|
||||
sources:
|
||||
- https://github.com/ziglang/zig
|
||||
tasks:
|
||||
|
||||
+17
-4
@@ -10,10 +10,14 @@ if(NOT CMAKE_INSTALL_PREFIX)
|
||||
"Directory to install zig to" FORCE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/c_flag_overrides.cmake)
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake)
|
||||
|
||||
project(zig C CXX)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
|
||||
|
||||
|
||||
set(ZIG_VERSION_MAJOR 0)
|
||||
set(ZIG_VERSION_MINOR 5)
|
||||
set(ZIG_VERSION_PATCH 0)
|
||||
@@ -42,6 +46,7 @@ message("Configuring zig version ${ZIG_VERSION}")
|
||||
set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")
|
||||
set(ZIG_STATIC_LLVM off CACHE BOOL "Prefer linking against static LLVM libraries")
|
||||
set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL "Disable copying lib/ files to install prefix")
|
||||
set(ZIG_ENABLE_MEM_PROFILE off CACHE BOOL "Activate memory usage instrumentation")
|
||||
|
||||
if(ZIG_STATIC)
|
||||
set(ZIG_STATIC_LLVM "on")
|
||||
@@ -433,16 +438,20 @@ set(ZIG_MAIN_SRC "${CMAKE_SOURCE_DIR}/src/main.cpp")
|
||||
# This is our shim which will be replaced by libuserland written in Zig.
|
||||
set(ZIG0_SHIM_SRC "${CMAKE_SOURCE_DIR}/src/userland.cpp")
|
||||
|
||||
if(ZIG_ENABLE_MEM_PROFILE)
|
||||
set(ZIG_SOURCES_MEM_PROFILE "${CMAKE_SOURCE_DIR}/src/memory_profiling.cpp")
|
||||
endif()
|
||||
|
||||
set(ZIG_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/analyze.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/ast_render.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/bigfloat.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/bigint.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/buffer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/c_tokenizer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/cache_hash.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/codegen.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/compiler.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/dump_analysis.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/errmsg.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/error.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/glibc.cpp"
|
||||
@@ -453,11 +462,10 @@ set(ZIG_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/os.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/parser.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/range_set.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/stack_report.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/target.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/tokenizer.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/translate_c.cpp"
|
||||
"${CMAKE_SOURCE_DIR}/src/util.cpp"
|
||||
"${ZIG_SOURCES_MEM_PROFILE}"
|
||||
)
|
||||
set(OPTIMIZED_C_SOURCES
|
||||
"${CMAKE_SOURCE_DIR}/src/blake2b.c"
|
||||
@@ -624,5 +632,10 @@ set_target_properties(zig PROPERTIES
|
||||
LINK_FLAGS ${EXE_LDFLAGS}
|
||||
)
|
||||
target_link_libraries(zig compiler "${LIBUSERLAND}")
|
||||
if(MSVC)
|
||||
target_link_libraries(zig ntdll.lib)
|
||||
elseif(MINGW)
|
||||
target_link_libraries(zig ntdll)
|
||||
endif()
|
||||
add_dependencies(zig zig_build_libuserland)
|
||||
install(TARGETS zig DESTINATION bin)
|
||||
|
||||
@@ -123,3 +123,61 @@ When developing on Linux, another option is available to you: `-Denable-wine`.
|
||||
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.
|
||||
|
||||
#### 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/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-self-hosted/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-self-hosted/translate_c.zig`. This code uses the Clang C API exposed by
|
||||
`src-self-hosted/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-self-hosted/translate_c.zig` to improve the behavior.
|
||||
|
||||
3. Run the relevant tests: `./zig build test-run-translated-c test-translate-c`
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||

|
||||
|
||||
A general-purpose programming language designed for **robustness**,
|
||||
**optimality**, and **maintainability**.
|
||||
A general-purpose programming language and toolchain for maintaining
|
||||
**robust**, **optimal**, and **reusable** software.
|
||||
|
||||
## Resources
|
||||
|
||||
|
||||
@@ -20,10 +20,10 @@ pub fn build(b: *Builder) !void {
|
||||
const rel_zig_exe = try fs.path.relative(b.allocator, b.build_root, b.zig_exe);
|
||||
const langref_out_path = fs.path.join(
|
||||
b.allocator,
|
||||
[_][]const u8{ b.cache_root, "langref.html" },
|
||||
&[_][]const u8{ b.cache_root, "langref.html" },
|
||||
) catch unreachable;
|
||||
var docgen_cmd = docgen_exe.run();
|
||||
docgen_cmd.addArgs([_][]const u8{
|
||||
docgen_cmd.addArgs(&[_][]const u8{
|
||||
rel_zig_exe,
|
||||
"doc" ++ fs.path.sep_str ++ "langref.html.in",
|
||||
langref_out_path,
|
||||
@@ -36,7 +36,7 @@ pub fn build(b: *Builder) !void {
|
||||
const test_step = b.step("test", "Run all the tests");
|
||||
|
||||
// find the stage0 build artifacts because we're going to re-use config.h and zig_cpp library
|
||||
const build_info = try b.exec([_][]const u8{
|
||||
const build_info = try b.exec(&[_][]const u8{
|
||||
b.zig_exe,
|
||||
"BUILD_INFO",
|
||||
});
|
||||
@@ -54,8 +54,9 @@ pub fn build(b: *Builder) !void {
|
||||
|
||||
var test_stage2 = b.addTest("src-self-hosted/test.zig");
|
||||
test_stage2.setBuildMode(builtin.Mode.Debug);
|
||||
test_stage2.addPackagePath("stage2_tests", "test/stage2/test.zig");
|
||||
|
||||
const fmt_build_zig = b.addFmt([_][]const u8{"build.zig"});
|
||||
const fmt_build_zig = b.addFmt(&[_][]const u8{"build.zig"});
|
||||
|
||||
var exe = b.addExecutable("zig", "src-self-hosted/main.zig");
|
||||
exe.setBuildMode(mode);
|
||||
@@ -72,9 +73,9 @@ pub fn build(b: *Builder) !void {
|
||||
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
|
||||
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
|
||||
const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;
|
||||
if (!skip_self_hosted) {
|
||||
// TODO re-enable this after https://github.com/ziglang/zig/issues/2377
|
||||
//test_step.dependOn(&exe.step);
|
||||
if (!skip_self_hosted and builtin.os == .linux) {
|
||||
// TODO evented I/O other OS's
|
||||
test_step.dependOn(&exe.step);
|
||||
}
|
||||
|
||||
const only_install_lib_files = b.option(bool, "lib-files-only", "Only install library files") orelse false;
|
||||
@@ -87,7 +88,7 @@ pub fn build(b: *Builder) !void {
|
||||
.source_dir = "lib",
|
||||
.install_dir = .Lib,
|
||||
.install_subdir = "zig",
|
||||
.exclude_extensions = [_][]const u8{ "test.zig", "README.md" },
|
||||
.exclude_extensions = &[_][]const u8{ "test.zig", "README.md" },
|
||||
});
|
||||
|
||||
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
|
||||
@@ -98,11 +99,7 @@ pub fn build(b: *Builder) !void {
|
||||
|
||||
const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
|
||||
test_stage2_step.dependOn(&test_stage2.step);
|
||||
|
||||
// TODO see https://github.com/ziglang/zig/issues/1364
|
||||
if (false) {
|
||||
test_step.dependOn(test_stage2_step);
|
||||
}
|
||||
test_step.dependOn(test_stage2_step);
|
||||
|
||||
var chosen_modes: [4]builtin.Mode = undefined;
|
||||
var chosen_mode_index: usize = 0;
|
||||
@@ -140,6 +137,7 @@ pub fn build(b: *Builder) !void {
|
||||
test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter, modes));
|
||||
test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter, modes));
|
||||
test_step.dependOn(tests.addTranslateCTests(b, test_filter));
|
||||
test_step.dependOn(tests.addRunTranslatedCTests(b, test_filter));
|
||||
test_step.dependOn(tests.addGenHTests(b, test_filter));
|
||||
test_step.dependOn(tests.addCompileErrorTests(b, test_filter, modes));
|
||||
test_step.dependOn(docs_step);
|
||||
@@ -151,16 +149,16 @@ fn dependOnLib(b: *Builder, lib_exe_obj: var, dep: LibraryDep) void {
|
||||
}
|
||||
const lib_dir = fs.path.join(
|
||||
b.allocator,
|
||||
[_][]const u8{ dep.prefix, "lib" },
|
||||
&[_][]const u8{ dep.prefix, "lib" },
|
||||
) catch unreachable;
|
||||
for (dep.system_libs.toSliceConst()) |lib| {
|
||||
const static_bare_name = if (mem.eql(u8, lib, "curses"))
|
||||
([]const u8)("libncurses.a")
|
||||
@as([]const u8, "libncurses.a")
|
||||
else
|
||||
b.fmt("lib{}.a", lib);
|
||||
b.fmt("lib{}.a", .{lib});
|
||||
const static_lib_name = fs.path.join(
|
||||
b.allocator,
|
||||
[_][]const u8{ lib_dir, static_bare_name },
|
||||
&[_][]const u8{ lib_dir, static_bare_name },
|
||||
) catch unreachable;
|
||||
const have_static = fileExists(static_lib_name) catch unreachable;
|
||||
if (have_static) {
|
||||
@@ -186,10 +184,10 @@ fn fileExists(filename: []const u8) !bool {
|
||||
}
|
||||
|
||||
fn addCppLib(b: *Builder, lib_exe_obj: var, cmake_binary_dir: []const u8, lib_name: []const u8) void {
|
||||
lib_exe_obj.addObjectFile(fs.path.join(b.allocator, [_][]const u8{
|
||||
lib_exe_obj.addObjectFile(fs.path.join(b.allocator, &[_][]const u8{
|
||||
cmake_binary_dir,
|
||||
"zig_cpp",
|
||||
b.fmt("{}{}{}", lib_exe_obj.target.libPrefix(), lib_name, lib_exe_obj.target.staticLibSuffix()),
|
||||
b.fmt("{}{}{}", .{ lib_exe_obj.target.libPrefix(), lib_name, lib_exe_obj.target.staticLibSuffix() }),
|
||||
}) catch unreachable);
|
||||
}
|
||||
|
||||
@@ -202,22 +200,22 @@ const LibraryDep = struct {
|
||||
};
|
||||
|
||||
fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
|
||||
const shared_mode = try b.exec([_][]const u8{ llvm_config_exe, "--shared-mode" });
|
||||
const shared_mode = try b.exec(&[_][]const u8{ llvm_config_exe, "--shared-mode" });
|
||||
const is_static = mem.startsWith(u8, shared_mode, "static");
|
||||
const libs_output = if (is_static)
|
||||
try b.exec([_][]const u8{
|
||||
try b.exec(&[_][]const u8{
|
||||
llvm_config_exe,
|
||||
"--libfiles",
|
||||
"--system-libs",
|
||||
})
|
||||
else
|
||||
try b.exec([_][]const u8{
|
||||
try b.exec(&[_][]const u8{
|
||||
llvm_config_exe,
|
||||
"--libs",
|
||||
});
|
||||
const includes_output = try b.exec([_][]const u8{ llvm_config_exe, "--includedir" });
|
||||
const libdir_output = try b.exec([_][]const u8{ llvm_config_exe, "--libdir" });
|
||||
const prefix_output = try b.exec([_][]const u8{ llvm_config_exe, "--prefix" });
|
||||
const includes_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--includedir" });
|
||||
const libdir_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--libdir" });
|
||||
const prefix_output = try b.exec(&[_][]const u8{ llvm_config_exe, "--prefix" });
|
||||
|
||||
var result = LibraryDep{
|
||||
.prefix = mem.tokenize(prefix_output, " \r\n").next().?,
|
||||
@@ -235,6 +233,9 @@ fn findLLVM(b: *Builder, llvm_config_exe: []const u8) !LibraryDep {
|
||||
if (fs.path.isAbsolute(lib_arg)) {
|
||||
try result.libs.append(lib_arg);
|
||||
} else {
|
||||
if (mem.endsWith(u8, lib_arg, ".lib")) {
|
||||
lib_arg = lib_arg[0 .. lib_arg.len - 4];
|
||||
}
|
||||
try result.system_libs.append(lib_arg);
|
||||
}
|
||||
}
|
||||
@@ -341,16 +342,16 @@ fn addCxxKnownPath(
|
||||
objname: []const u8,
|
||||
errtxt: ?[]const u8,
|
||||
) !void {
|
||||
const path_padded = try b.exec([_][]const u8{
|
||||
const path_padded = try b.exec(&[_][]const u8{
|
||||
ctx.cxx_compiler,
|
||||
b.fmt("-print-file-name={}", objname),
|
||||
b.fmt("-print-file-name={}", .{objname}),
|
||||
});
|
||||
const path_unpadded = mem.tokenize(path_padded, "\r\n").next().?;
|
||||
if (mem.eql(u8, path_unpadded, objname)) {
|
||||
if (errtxt) |msg| {
|
||||
warn("{}", msg);
|
||||
warn("{}", .{msg});
|
||||
} else {
|
||||
warn("Unable to determine path to {}\n", objname);
|
||||
warn("Unable to determine path to {}\n", .{objname});
|
||||
}
|
||||
return error.RequiredLibraryNotFound;
|
||||
}
|
||||
@@ -373,6 +374,7 @@ fn addLibUserlandStep(b: *Builder, mode: builtin.Mode) void {
|
||||
artifact.bundle_compiler_rt = true;
|
||||
artifact.setTarget(builtin.arch, builtin.os, builtin.abi);
|
||||
artifact.setBuildMode(mode);
|
||||
artifact.force_pic = true;
|
||||
if (mode != .Debug) {
|
||||
artifact.strip = true;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ set -e
|
||||
|
||||
BUILDDIR="$(pwd)"
|
||||
|
||||
sudo sh -c 'echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-9 main" >> /etc/apt/sources.list'
|
||||
sudo sh -c 'echo "deb http://apt.llvm.org/bionic/ llvm-toolchain-bionic-9 main" >> /etc/apt/sources.list'
|
||||
wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
|
||||
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
|
||||
sudo apt-get update -q
|
||||
@@ -14,6 +14,10 @@ sudo apt-get remove -y llvm-*
|
||||
sudo rm -rf /usr/local/*
|
||||
sudo apt-get install -y libxml2-dev libclang-9-dev llvm-9 llvm-9-dev cmake s3cmd gcc-7 g++-7 qemu
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git config core.abbrev 9
|
||||
|
||||
export CC=gcc-7
|
||||
export CXX=g++-7
|
||||
mkdir build
|
||||
@@ -21,11 +25,12 @@ cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
||||
make -j2 install
|
||||
./zig build test -Denable-qemu
|
||||
VERSION="$(./zig version)"
|
||||
|
||||
if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
ARTIFACTSDIR="$BUILDDIR/artifacts"
|
||||
mkdir "$ARTIFACTSDIR"
|
||||
docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm9-1 -j2 $BUILD_SOURCEVERSION
|
||||
docker run -i --mount type=bind,source="$ARTIFACTSDIR",target=/z ziglang/static-base:llvm9-x86_64 -j2 $BUILD_SOURCEVERSION
|
||||
TARBALL="$(ls $ARTIFACTSDIR)"
|
||||
mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
|
||||
s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$ARTIFACTSDIR/$TARBALL" s3://ziglang.org/builds/
|
||||
@@ -40,7 +45,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
||||
|
||||
s3cmd put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/linux-$VERSION.json"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/x86_64-linux-$VERSION.json"
|
||||
|
||||
# `set -x` causes these variables to be mangled.
|
||||
# See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
|
||||
@@ -48,4 +53,5 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
echo "##vso[task.setvariable variable=tarball;isOutput=true]$TARBALL"
|
||||
echo "##vso[task.setvariable variable=shasum;isOutput=true]$SHASUM"
|
||||
echo "##vso[task.setvariable variable=bytesize;isOutput=true]$BYTESIZE"
|
||||
echo "##vso[task.setvariable variable=version;isOutput=true]$VERSION"
|
||||
fi
|
||||
|
||||
+25
-9
@@ -8,7 +8,9 @@ system_profiler SPHardwareDataType
|
||||
brew install s3cmd gcc@8
|
||||
|
||||
ZIGDIR="$(pwd)"
|
||||
CACHE_BASENAME="llvm+clang-10.0.0-macos-x86_64-gcc8-release"
|
||||
LLVMVER="10.0.0"
|
||||
ARCH="x86_64"
|
||||
CACHE_BASENAME="llvm+clang+lld-$LLVMVER-$ARCH-macos-gcc8-release"
|
||||
PREFIX="$HOME/$CACHE_BASENAME"
|
||||
TMPDIR="$HOME/tmpz"
|
||||
JOBS="-j2"
|
||||
@@ -44,18 +46,27 @@ else
|
||||
rm $PREFIX/lib/libz*dylib
|
||||
|
||||
cd $TMPDIR
|
||||
wget https://releases.llvm.org/10.0.0/llvm-10.0.0.src.tar.xz
|
||||
tar xf llvm-10.0.0.src.tar.xz
|
||||
cd llvm-10.0.0.src/
|
||||
wget https://releases.llvm.org/$LLVMVER/llvm-$LLVMVER.src.tar.xz
|
||||
tar xf llvm-$LLVMVER.src.tar.xz
|
||||
cd llvm-$LLVMVER.src/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Release -DLLVM_EXPERIMENTAL_TARGETS_TO_BUILD="AVR" -DLLVM_ENABLE_LIBXML2=OFF -DLLVM_ENABLE_TERMINFO=OFF
|
||||
make $JOBS install
|
||||
|
||||
cd $TMPDIR
|
||||
wget https://releases.llvm.org/10.0.0/cfe-10.0.0.src.tar.xz
|
||||
tar xf cfe-10.0.0.src.tar.xz
|
||||
cd cfe-10.0.0.src/
|
||||
wget https://releases.llvm.org/$LLVMVER/cfe-$LLVMVER.src.tar.xz
|
||||
tar xf cfe-$LLVMVER.src.tar.xz
|
||||
cd cfe-$LLVMVER.src/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Release
|
||||
make $JOBS install
|
||||
|
||||
cd $TMPDIR
|
||||
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVMVER/lld-$LLVMVER.src.tar.xz
|
||||
tar xf lld-$LLVMVER.src.tar.xz
|
||||
cd lld-$LLVMVER.src/
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_INSTALL_PREFIX=$PREFIX -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_BUILD_TYPE=Release
|
||||
@@ -68,6 +79,11 @@ else
|
||||
fi
|
||||
|
||||
cd $ZIGDIR
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git config core.abbrev 9
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=$(pwd)/release -DZIG_STATIC=ON
|
||||
@@ -81,7 +97,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
rmdir release/bin
|
||||
|
||||
VERSION=$(release/zig version)
|
||||
DIRNAME="zig-macos-x86_64-$VERSION"
|
||||
DIRNAME="zig-macos-$ARCH-$VERSION"
|
||||
TARBALL="$DIRNAME.tar.xz"
|
||||
mv release "$DIRNAME"
|
||||
tar cfJ "$TARBALL" "$DIRNAME"
|
||||
@@ -99,7 +115,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
||||
|
||||
s3cmd put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/macos-$VERSION.json"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/$ARCH-macos-$VERSION.json"
|
||||
|
||||
# `set -x` causes these variables to be mangled.
|
||||
# See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
|
||||
# We do not set -x because this would leak the oauth access token.
|
||||
set +x
|
||||
|
||||
set -e
|
||||
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y curl jq
|
||||
|
||||
OAUTH_TOKEN="$(cat "$DOWNLOADSECUREFILE_SECUREFILEPATH")"
|
||||
./ci/srht/on_master_success "$VERSION" "$OAUTH_TOKEN"
|
||||
+7
-15
@@ -14,7 +14,7 @@ jobs:
|
||||
displayName: 'Build and test'
|
||||
- job: BuildLinux
|
||||
pool:
|
||||
vmImage: 'ubuntu-16.04'
|
||||
vmImage: 'ubuntu-18.04'
|
||||
|
||||
timeoutInMinutes: 360
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
- script: ci/azure/windows_script.bat
|
||||
name: main
|
||||
displayName: 'Build and test'
|
||||
- job: UpdateDownloadPage
|
||||
- job: OnMasterSuccess
|
||||
dependsOn:
|
||||
- BuildMacOS
|
||||
- BuildLinux
|
||||
@@ -53,20 +53,12 @@ jobs:
|
||||
strategy:
|
||||
maxParallel: 1
|
||||
pool:
|
||||
vmImage: 'ubuntu-16.04'
|
||||
vmImage: 'ubuntu-18.04'
|
||||
variables:
|
||||
macos_tarball: $[ dependencies.BuildMacOS.outputs['main.tarball'] ]
|
||||
macos_shasum: $[ dependencies.BuildMacOS.outputs['main.shasum'] ]
|
||||
macos_bytesize: $[ dependencies.BuildMacOS.outputs['main.bytesize'] ]
|
||||
linux_tarball: $[ dependencies.BuildLinux.outputs['main.tarball'] ]
|
||||
linux_shasum: $[ dependencies.BuildLinux.outputs['main.shasum'] ]
|
||||
linux_bytesize: $[ dependencies.BuildLinux.outputs['main.bytesize'] ]
|
||||
windows_tarball: $[ dependencies.BuildWindows.outputs['main.tarball'] ]
|
||||
windows_shasum: $[ dependencies.BuildWindows.outputs['main.shasum'] ]
|
||||
windows_bytesize: $[ dependencies.BuildWindows.outputs['main.bytesize'] ]
|
||||
version: $[ dependencies.BuildLinux.outputs['main.version'] ]
|
||||
steps:
|
||||
- task: DownloadSecureFile@1
|
||||
inputs:
|
||||
secureFile: s3cfg
|
||||
- script: ci/azure/update_download_page
|
||||
displayName: 'Update download page'
|
||||
secureFile: oauth_token
|
||||
- script: ci/azure/on_master_success
|
||||
displayName: 'master branch success hook'
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
SRCDIR=$(pwd)
|
||||
rm -rf .git
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install -y s3cmd curl jq
|
||||
|
||||
cd "$HOME"
|
||||
wget "https://ziglang.org/builds/$LINUX_TARBALL"
|
||||
tar xf $LINUX_TARBALL
|
||||
ZIGDIR=$(basename -s .tar.xz $LINUX_TARBALL)
|
||||
ZIG="$ZIGDIR/zig"
|
||||
LANGREF="$ZIGDIR/langref.html"
|
||||
VERSION=$($ZIG version)
|
||||
SRCTARBALLDIR="zig-$VERSION"
|
||||
export SRC_TARBALL="$SRCTARBALLDIR.tar.xz"
|
||||
mv "$SRCDIR" "$SRCTARBALLDIR"
|
||||
tar cfJ "$SRC_TARBALL" "$SRCTARBALLDIR"
|
||||
export SRC_SHASUM=$(sha256sum $SRC_TARBALL | cut '-d ' -f1)
|
||||
export SRC_BYTESIZE=$(wc -c < $SRC_TARBALL)
|
||||
|
||||
# the freebsd build has to be there too
|
||||
FREEBSD_JSON=$(curl --fail "https://ziglang.org/builds/freebsd-$VERSION.json" || exit 1)
|
||||
export FREEBSD_TARBALL="$(echo "$FREEBSD_JSON" | jq .tarball -r)"
|
||||
export FREEBSD_BYTESIZE="$(echo "$FREEBSD_JSON" | jq .size -r)"
|
||||
export FREEBSD_SHASUM="$(echo "$FREEBSD_JSON" | jq .shasum -r)"
|
||||
|
||||
git clone https://github.com/ziglang/www.ziglang.org --depth 1
|
||||
cd www.ziglang.org
|
||||
export MASTER_DATE=$(date +%Y-%m-%d)
|
||||
env
|
||||
"../$ZIG" run update-download-page.zig
|
||||
|
||||
mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"
|
||||
s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "../$SRC_TARBALL" s3://ziglang.org/builds/
|
||||
s3cmd put -P "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
s3cmd put -P www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
s3cmd put -P www/download/index.json s3://ziglang.org/download/index.json --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
@@ -6,5 +6,5 @@ set -e
|
||||
pacman -Su --needed --noconfirm
|
||||
pacman -S --needed --noconfirm wget p7zip python3-pip
|
||||
pip install s3cmd
|
||||
wget -nv "https://ziglang.org/deps/llvm%2bclang-10.0.0-win64-msvc-release.tar.xz"
|
||||
wget -nv "https://ziglang.org/deps/llvm%2bclang%2blld-10.0.0-x86_64-windows-msvc-mt.tar.xz"
|
||||
tar xf llvm+clang-10.0.0-win64-msvc-release.tar.xz
|
||||
|
||||
@@ -11,15 +11,18 @@ SET "MSYSTEM=%PREVMSYSTEM%"
|
||||
|
||||
SET "ZIGBUILDDIR=%SRCROOT%\build"
|
||||
SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\dist"
|
||||
SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang-10.0.0-win64-msvc-release"
|
||||
SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang+lld-10.0.0-x86_64-windows-msvc-mt"
|
||||
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
|
||||
|
||||
REM Make the `zig version` number consistent.
|
||||
REM This will affect the cmake command below.
|
||||
git.exe config core.abbrev 9
|
||||
|
||||
mkdir %ZIGBUILDDIR%
|
||||
cd %ZIGBUILDDIR%
|
||||
REM Here we use MinSizeRel instead of Release to work around https://github.com/ziglang/zig/issues/3024
|
||||
cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=MinSizeRel || exit /b
|
||||
msbuild /p:Configuration=MinSizeRel INSTALL.vcxproj || exit /b
|
||||
cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=Release || exit /b
|
||||
msbuild /maxcpucount /p:Configuration=Release INSTALL.vcxproj || exit /b
|
||||
|
||||
"%ZIGINSTALLDIR%\bin\zig.exe" build test || exit /b
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ if [ "${BUILD_REASON}" != "PullRequest" ]; then
|
||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
||||
|
||||
s3cmd put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/windows-$VERSION.json"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/x86_64-windows-$VERSION.json"
|
||||
|
||||
# `set -x` causes these variables to be mangled.
|
||||
# See https://developercommunity.visualstudio.com/content/problem/375679/pipeline-variable-incorrectly-inserts-single-quote.html
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
kind: pipeline
|
||||
name: test-aarch64-linux-musl
|
||||
|
||||
platform:
|
||||
arch: arm64
|
||||
|
||||
steps:
|
||||
- name: build-and-test
|
||||
image: ziglang/static-base:llvm9-1
|
||||
environment:
|
||||
SRHT_OAUTH_TOKEN:
|
||||
from_secret: SRHT_OAUTH_TOKEN
|
||||
AWS_ACCESS_KEY_ID:
|
||||
from_secret: AWS_ACCESS_KEY_ID
|
||||
AWS_SECRET_ACCESS_KEY:
|
||||
from_secret: AWS_SECRET_ACCESS_KEY
|
||||
commands:
|
||||
- ./ci/drone/linux_script
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
TRIPLEARCH="$(uname -m)"
|
||||
BUILDDIR="$(pwd)"
|
||||
DISTDIR="$(pwd)/dist"
|
||||
|
||||
apk update
|
||||
apk add py3-pip xz perl-utils jq curl
|
||||
pip3 install s3cmd
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git config core.abbrev 9
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release "-DCMAKE_INSTALL_PREFIX=$DISTDIR" -DZIG_STATIC=ON -DCMAKE_PREFIX_PATH=/deps/local
|
||||
|
||||
make -j$(nproc) install
|
||||
./zig build test-fmt test-behavior test-std test-compiler-rt -Dskip-release -Dskip-non-native
|
||||
# TODO test-compare-output is hitting https://github.com/ziglang/zig/issues/3526
|
||||
./zig build test-standalone test-stack-traces
|
||||
# TODO test-cli is hitting https://github.com/ziglang/zig/issues/3526
|
||||
./zig build test-asm-link test-runtime-safety
|
||||
# TODO test-translate-c is hitting https://github.com/ziglang/zig/issues/3526
|
||||
./zig build test-gen-h
|
||||
# TODO test-compile-errors is hitting https://github.com/ziglang/zig/issues/3526
|
||||
# TODO building docs is hitting https://github.com/ziglang/zig/issues/3526
|
||||
|
||||
# TODO full test suite:
|
||||
#./zig build test
|
||||
|
||||
if [ -z "$DRONE_PULL_REQUEST" ]; then
|
||||
mv ../LICENSE "$DISTDIR/"
|
||||
# TODO uncomment when the docs are generated
|
||||
# mv ../zig-cache/langref.html "$DISTDIR/"
|
||||
mv "$DISTDIR/bin/zig" "$DISTDIR/"
|
||||
rmdir "$DISTDIR/bin"
|
||||
|
||||
GITBRANCH="$DRONE_BRANCH"
|
||||
VERSION="$("$DISTDIR/zig" version)"
|
||||
DIRNAME="zig-linux-$TRIPLEARCH-$VERSION"
|
||||
TARBALL="$DIRNAME.tar.xz"
|
||||
mv "$DISTDIR" "$DIRNAME"
|
||||
tar cfJ "$TARBALL" "$DIRNAME"
|
||||
|
||||
s3cmd put -P --add-header="cache-control: public, max-age=31536000, immutable" "$TARBALL" s3://ziglang.org/builds/
|
||||
|
||||
SHASUM=$(shasum -a 256 $TARBALL | cut '-d ' -f1)
|
||||
BYTESIZE=$(wc -c < $TARBALL)
|
||||
|
||||
JSONFILE="$TRIPLEARCH-linux-$GITBRANCH.json"
|
||||
touch $JSONFILE
|
||||
echo "{\"tarball\": \"$TARBALL\"," >>$JSONFILE
|
||||
echo "\"shasum\": \"$SHASUM\"," >>$JSONFILE
|
||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
||||
|
||||
s3cmd put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/$TRIPLEARCH-linux-$VERSION.json"
|
||||
if [ "$GITBRANCH" = "master" ]; then
|
||||
# avoid leaking oauth token
|
||||
set +x
|
||||
|
||||
cd "$BUILDDIR"
|
||||
./ci/srht/on_master_success "$VERSION" "$SRHT_OAUTH_TOKEN"
|
||||
fi
|
||||
fi
|
||||
+16
-2
@@ -13,9 +13,14 @@ wget -nv "https://ziglang.org/builds/$CACHE_BASENAME.tar.xz"
|
||||
tar xf "$CACHE_BASENAME.tar.xz"
|
||||
|
||||
cd $ZIGDIR
|
||||
|
||||
# Make the `zig version` number consistent.
|
||||
# This will affect the cmake command below.
|
||||
git config core.abbrev 9
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=$(pwd)/release -DZIG_STATIC=ON
|
||||
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PREFIX "-DCMAKE_INSTALL_PREFIX=$(pwd)/release" -DZIG_STATIC=ON
|
||||
make $JOBS install
|
||||
|
||||
release/bin/zig build test-fmt
|
||||
@@ -80,5 +85,14 @@ if [ -f ~/.s3cfg ]; then
|
||||
echo "\"size\": \"$BYTESIZE\"}" >>$JSONFILE
|
||||
|
||||
s3cmd put -P --add-header="Cache-Control: max-age=0, must-revalidate" "$JSONFILE" "s3://ziglang.org/builds/$JSONFILE"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/freebsd-$VERSION.json"
|
||||
s3cmd put -P "$JSONFILE" "s3://ziglang.org/builds/x86_64-freebsd-$VERSION.json"
|
||||
|
||||
if [ "$GITBRANCH" = "master" ]; then
|
||||
# avoid leaking oauth token
|
||||
set +x
|
||||
|
||||
OAUTH_TOKEN="$(cat ~/.oauth_token)"
|
||||
cd "$ZIGDIR"
|
||||
./ci/srht/on_master_success "$VERSION" "$OAUTH_TOKEN"
|
||||
fi
|
||||
fi
|
||||
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
# This script must run on a lot of different platforms.
|
||||
# It assumes that the following things are installed:
|
||||
# * curl
|
||||
# * jq
|
||||
# * cat
|
||||
|
||||
# We do not set -x because this would leak the oauth access token.
|
||||
set +x
|
||||
|
||||
set -e
|
||||
|
||||
VERSION="$1"
|
||||
OAUTH_TOKEN="$2"
|
||||
YML_FILE="tmp.yml"
|
||||
|
||||
cat <<EOF >"$YML_FILE"
|
||||
image: alpine/latest
|
||||
packages:
|
||||
- py3-pip
|
||||
- curl
|
||||
- jq
|
||||
- xz
|
||||
secrets:
|
||||
- 6c60aaee-92e7-4e7d-812c-114817689b4d
|
||||
sources:
|
||||
- https://github.com/ziglang/zig
|
||||
tasks:
|
||||
- build: cd zig && ./ci/srht/update_download_page $VERSION
|
||||
EOF
|
||||
|
||||
jq <$YML_FILE -sR '{
|
||||
"manifest": .,
|
||||
}' | curl \
|
||||
-H Authorization:"token $OAUTH_TOKEN" \
|
||||
-H Content-Type:application/json \
|
||||
-X POST \
|
||||
-d @- "https://builds.sr.ht/api/jobs"
|
||||
Executable
+79
@@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -x
|
||||
set -e
|
||||
|
||||
VERSION="$1"
|
||||
SRCDIR="$(pwd)"
|
||||
NATIVE_TARBALL="zig-linux-$(uname -m)-$VERSION.tar.xz"
|
||||
|
||||
# Check for all the builds being completed. It's expected that this script is run several times
|
||||
# before they are all complete.
|
||||
AARCH64_LINUX_JSON_URL="https://ziglang.org/builds/aarch64-linux-$VERSION.json"
|
||||
X86_64_LINUX_JSON_URL="https://ziglang.org/builds/x86_64-linux-$VERSION.json"
|
||||
X86_64_WINDOWS_JSON_URL="https://ziglang.org/builds/x86_64-windows-$VERSION.json"
|
||||
X86_64_MACOS_JSON_URL="https://ziglang.org/builds/x86_64-macos-$VERSION.json"
|
||||
X86_64_FREEBSD_JSON_URL="https://ziglang.org/builds/x86_64-freebsd-$VERSION.json"
|
||||
|
||||
# If any of these fail, it's not really this job failing; rather we have detected
|
||||
# that this job will be called again later when other jobs have completed.
|
||||
curl --fail -I "$AARCH64_LINUX_JSON_URL" >/dev/null || exit 0
|
||||
curl --fail -I "$X86_64_LINUX_JSON_URL" >/dev/null || exit 0
|
||||
curl --fail -I "$X86_64_WINDOWS_JSON_URL" >/dev/null || exit 0
|
||||
curl --fail -I "$X86_64_MACOS_JSON_URL" >/dev/null || exit 0
|
||||
curl --fail -I "$X86_64_FREEBSD_JSON_URL" >/dev/null || exit 0
|
||||
|
||||
# Without --user, this gave me:
|
||||
# ERROR: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied
|
||||
pip3 install s3cmd --user
|
||||
S3CMD="$HOME/.local/bin/s3cmd"
|
||||
|
||||
rm -rf .git
|
||||
|
||||
cd "$HOME"
|
||||
wget "https://ziglang.org/builds/$NATIVE_TARBALL"
|
||||
tar xf "$NATIVE_TARBALL"
|
||||
ZIGDIR=$(basename $NATIVE_TARBALL .tar.xz)
|
||||
ZIG="$ZIGDIR/zig"
|
||||
LANGREF="$ZIGDIR/langref.html"
|
||||
SRCTARBALLDIR="zig-$VERSION"
|
||||
export SRC_TARBALL="$SRCTARBALLDIR.tar.xz"
|
||||
mv "$SRCDIR" "$SRCTARBALLDIR"
|
||||
tar cfJ "$SRC_TARBALL" "$SRCTARBALLDIR"
|
||||
export SRC_SHASUM=$(sha256sum $SRC_TARBALL | cut '-d ' -f1)
|
||||
export SRC_BYTESIZE=$(wc -c < $SRC_TARBALL)
|
||||
|
||||
X86_64_WINDOWS_JSON=$(curl --fail "$X86_64_WINDOWS_JSON_URL" || exit 1)
|
||||
export X86_64_WINDOWS_TARBALL="$(echo "$X86_64_WINDOWS_JSON" | jq .tarball -r)"
|
||||
export X86_64_WINDOWS_BYTESIZE="$(echo "$X86_64_WINDOWS_JSON" | jq .size -r)"
|
||||
export X86_64_WINDOWS_SHASUM="$(echo "$X86_64_WINDOWS_JSON" | jq .shasum -r)"
|
||||
|
||||
X86_64_MACOS_JSON=$(curl --fail "$X86_64_MACOS_JSON_URL" || exit 1)
|
||||
export X86_64_MACOS_TARBALL="$(echo "$X86_64_MACOS_JSON" | jq .tarball -r)"
|
||||
export X86_64_MACOS_BYTESIZE="$(echo "$X86_64_MACOS_JSON" | jq .size -r)"
|
||||
export X86_64_MACOS_SHASUM="$(echo "$X86_64_MACOS_JSON" | jq .shasum -r)"
|
||||
|
||||
X86_64_LINUX_JSON=$(curl --fail "$X86_64_LINUX_JSON_URL" || exit 1)
|
||||
export X86_64_LINUX_TARBALL="$(echo "$X86_64_LINUX_JSON" | jq .tarball -r)"
|
||||
export X86_64_LINUX_BYTESIZE="$(echo "$X86_64_LINUX_JSON" | jq .size -r)"
|
||||
export X86_64_LINUX_SHASUM="$(echo "$X86_64_LINUX_JSON" | jq .shasum -r)"
|
||||
|
||||
AARCH64_LINUX_JSON=$(curl --fail "$AARCH64_LINUX_JSON_URL" || exit 1)
|
||||
export AARCH64_LINUX_TARBALL="$(echo "$AARCH64_LINUX_JSON" | jq .tarball -r)"
|
||||
export AARCH64_LINUX_BYTESIZE="$(echo "$AARCH64_LINUX_JSON" | jq .size -r)"
|
||||
export AARCH64_LINUX_SHASUM="$(echo "$AARCH64_LINUX_JSON" | jq .shasum -r)"
|
||||
|
||||
X86_64_FREEBSD_JSON=$(curl --fail "$X86_64_FREEBSD_JSON_URL" || exit 1)
|
||||
export X86_64_FREEBSD_TARBALL="$(echo "$X86_64_FREEBSD_JSON" | jq .tarball -r)"
|
||||
export X86_64_FREEBSD_BYTESIZE="$(echo "$X86_64_FREEBSD_JSON" | jq .size -r)"
|
||||
export X86_64_FREEBSD_SHASUM="$(echo "$X86_64_FREEBSD_JSON" | jq .shasum -r)"
|
||||
|
||||
git clone https://github.com/ziglang/www.ziglang.org --depth 1
|
||||
cd www.ziglang.org
|
||||
export MASTER_DATE="$(date +%Y-%m-%d)"
|
||||
"../$ZIG" run update-download-page.zig
|
||||
|
||||
$S3CMD put -P --no-mime-magic --add-header="cache-control: public, max-age=31536000, immutable" "../$SRC_TARBALL" s3://ziglang.org/builds/
|
||||
$S3CMD put -P --no-mime-magic "../$LANGREF" s3://ziglang.org/documentation/master/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
$S3CMD put -P --no-mime-magic www/download/index.html s3://ziglang.org/download/index.html --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
$S3CMD put -P --no-mime-magic www/download/index.json s3://ziglang.org/download/index.json --add-header="Cache-Control: max-age=0, must-revalidate"
|
||||
@@ -0,0 +1,13 @@
|
||||
if(MSVC)
|
||||
set(CMAKE_C_FLAGS_DEBUG_INIT
|
||||
"/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
|
||||
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL_INIT
|
||||
"/MT /O1 /Ob1 /D NDEBUG")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELEASE_INIT
|
||||
"/MT /O2 /Ob1 /D NDEBUG")
|
||||
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT
|
||||
"/MT /Zi /O2 /Ob1 /D NDEBUG")
|
||||
endif()
|
||||
@@ -0,0 +1,13 @@
|
||||
if(MSVC)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG_INIT
|
||||
"/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_MINSIZEREL_INIT
|
||||
"/MT /O1 /Ob1 /D NDEBUG")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE_INIT
|
||||
"/MT /O2 /Ob1 /D NDEBUG")
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO_INIT
|
||||
"/MT /Zi /O2 /Ob1 /D NDEBUG")
|
||||
endif()
|
||||
+171
-162
@@ -10,13 +10,13 @@ const testing = std.testing;
|
||||
|
||||
const max_doc_file_size = 10 * 1024 * 1024;
|
||||
|
||||
const exe_ext = std.build.Target(std.build.Target.Native).exeFileExt();
|
||||
const obj_ext = std.build.Target(std.build.Target.Native).oFileExt();
|
||||
const exe_ext = @as(std.build.Target, std.build.Target.Native).exeFileExt();
|
||||
const obj_ext = @as(std.build.Target, std.build.Target.Native).oFileExt();
|
||||
const tmp_dir_name = "docgen_tmp";
|
||||
const test_out_path = tmp_dir_name ++ fs.path.sep_str ++ "test" ++ exe_ext;
|
||||
|
||||
pub fn main() !void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator);
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const allocator = &arena.allocator;
|
||||
@@ -51,7 +51,7 @@ pub fn main() !void {
|
||||
var toc = try genToc(allocator, &tokenizer);
|
||||
|
||||
try fs.makePath(allocator, tmp_dir_name);
|
||||
defer fs.deleteTree(allocator, tmp_dir_name) catch {};
|
||||
defer fs.deleteTree(tmp_dir_name) catch {};
|
||||
|
||||
try genHtml(allocator, &tokenizer, &toc, &buffered_out_stream.stream, zig_exe);
|
||||
try buffered_out_stream.flush();
|
||||
@@ -215,32 +215,33 @@ const Tokenizer = struct {
|
||||
}
|
||||
};
|
||||
|
||||
fn parseError(tokenizer: *Tokenizer, token: Token, comptime fmt: []const u8, args: ...) anyerror {
|
||||
fn parseError(tokenizer: *Tokenizer, token: Token, comptime fmt: []const u8, args: var) anyerror {
|
||||
const loc = tokenizer.getTokenLocation(token);
|
||||
warn("{}:{}:{}: error: " ++ fmt ++ "\n", tokenizer.source_file_name, loc.line + 1, loc.column + 1, args);
|
||||
const args_prefix = .{ tokenizer.source_file_name, loc.line + 1, loc.column + 1 };
|
||||
warn("{}:{}:{}: error: " ++ fmt ++ "\n", args_prefix ++ args);
|
||||
if (loc.line_start <= loc.line_end) {
|
||||
warn("{}\n", tokenizer.buffer[loc.line_start..loc.line_end]);
|
||||
warn("{}\n", .{tokenizer.buffer[loc.line_start..loc.line_end]});
|
||||
{
|
||||
var i: usize = 0;
|
||||
while (i < loc.column) : (i += 1) {
|
||||
warn(" ");
|
||||
warn(" ", .{});
|
||||
}
|
||||
}
|
||||
{
|
||||
const caret_count = token.end - token.start;
|
||||
var i: usize = 0;
|
||||
while (i < caret_count) : (i += 1) {
|
||||
warn("~");
|
||||
warn("~", .{});
|
||||
}
|
||||
}
|
||||
warn("\n");
|
||||
warn("\n", .{});
|
||||
}
|
||||
return error.ParseError;
|
||||
}
|
||||
|
||||
fn assertToken(tokenizer: *Tokenizer, token: Token, id: Token.Id) !void {
|
||||
if (token.id != id) {
|
||||
return parseError(tokenizer, token, "expected {}, found {}", @tagName(id), @tagName(token.id));
|
||||
return parseError(tokenizer, token, "expected {}, found {}", .{ @tagName(id), @tagName(token.id) });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,7 +340,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
switch (token.id) {
|
||||
Token.Id.Eof => {
|
||||
if (header_stack_size != 0) {
|
||||
return parseError(tokenizer, token, "unbalanced headers");
|
||||
return parseError(tokenizer, token, "unbalanced headers", .{});
|
||||
}
|
||||
try toc.write(" </ul>\n");
|
||||
break;
|
||||
@@ -370,13 +371,18 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
.Separator => continue,
|
||||
.TagContent => {
|
||||
const param = tokenizer.buffer[bracket_tok.start..bracket_tok.end];
|
||||
if (mem.eql(u8, param, "3col")) {
|
||||
columns = 3;
|
||||
if (mem.eql(u8, param, "2col")) {
|
||||
columns = 2;
|
||||
} else {
|
||||
return parseError(tokenizer, bracket_tok, "unrecognized header_open param: {}", param);
|
||||
return parseError(
|
||||
tokenizer,
|
||||
bracket_tok,
|
||||
"unrecognized header_open param: {}",
|
||||
.{param},
|
||||
);
|
||||
}
|
||||
},
|
||||
else => return parseError(tokenizer, bracket_tok, "invalid header_open token"),
|
||||
else => return parseError(tokenizer, bracket_tok, "invalid header_open token", .{}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,15 +397,15 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
},
|
||||
});
|
||||
if (try urls.put(urlized, tag_token)) |entry| {
|
||||
parseError(tokenizer, tag_token, "duplicate header url: #{}", urlized) catch {};
|
||||
parseError(tokenizer, entry.value, "other tag here") catch {};
|
||||
parseError(tokenizer, tag_token, "duplicate header url: #{}", .{urlized}) catch {};
|
||||
parseError(tokenizer, entry.value, "other tag here", .{}) catch {};
|
||||
return error.ParseError;
|
||||
}
|
||||
if (last_action == Action.Open) {
|
||||
try toc.writeByte('\n');
|
||||
try toc.writeByteNTimes(' ', header_stack_size * 4);
|
||||
if (last_columns) |n| {
|
||||
try toc.print("<ul style=\"columns: {}\">\n", n);
|
||||
try toc.print("<ul style=\"columns: {}\">\n", .{n});
|
||||
} else {
|
||||
try toc.write("<ul>\n");
|
||||
}
|
||||
@@ -408,10 +414,10 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
}
|
||||
last_columns = columns;
|
||||
try toc.writeByteNTimes(' ', 4 + header_stack_size * 4);
|
||||
try toc.print("<li><a id=\"toc-{}\" href=\"#{}\">{}</a>", urlized, urlized, content);
|
||||
try toc.print("<li><a id=\"toc-{}\" href=\"#{}\">{}</a>", .{ urlized, urlized, content });
|
||||
} else if (mem.eql(u8, tag_name, "header_close")) {
|
||||
if (header_stack_size == 0) {
|
||||
return parseError(tokenizer, tag_token, "unbalanced close header");
|
||||
return parseError(tokenizer, tag_token, "unbalanced close header", .{});
|
||||
}
|
||||
header_stack_size -= 1;
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
@@ -442,7 +448,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
try nodes.append(Node{ .SeeAlso = list.toOwnedSlice() });
|
||||
break;
|
||||
},
|
||||
else => return parseError(tokenizer, see_also_tok, "invalid see_also token"),
|
||||
else => return parseError(tokenizer, see_also_tok, "invalid see_also token", .{}),
|
||||
}
|
||||
}
|
||||
} else if (mem.eql(u8, tag_name, "link")) {
|
||||
@@ -459,7 +465,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
break :blk tokenizer.buffer[explicit_text.start..explicit_text.end];
|
||||
},
|
||||
else => return parseError(tokenizer, tok, "invalid link token"),
|
||||
else => return parseError(tokenizer, tok, "invalid link token", .{}),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -482,7 +488,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
},
|
||||
Token.Id.BracketClose => {},
|
||||
else => return parseError(tokenizer, token, "invalid token"),
|
||||
else => return parseError(tokenizer, token, "invalid token", .{}),
|
||||
}
|
||||
const code_kind_str = tokenizer.buffer[code_kind_tok.start..code_kind_tok.end];
|
||||
var code_kind_id: Code.Id = undefined;
|
||||
@@ -512,7 +518,7 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
code_kind_id = Code.Id{ .Obj = null };
|
||||
is_inline = true;
|
||||
} else {
|
||||
return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", code_kind_str);
|
||||
return parseError(tokenizer, code_kind_tok, "unrecognized code kind: {}", .{code_kind_str});
|
||||
}
|
||||
|
||||
var mode = builtin.Mode.Debug;
|
||||
@@ -550,7 +556,12 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
break content_tok;
|
||||
} else {
|
||||
return parseError(tokenizer, end_code_tag, "invalid token inside code_begin: {}", end_tag_name);
|
||||
return parseError(
|
||||
tokenizer,
|
||||
end_code_tag,
|
||||
"invalid token inside code_begin: {}",
|
||||
.{end_tag_name},
|
||||
);
|
||||
}
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
} else
|
||||
@@ -575,15 +586,20 @@ fn genToc(allocator: *mem.Allocator, tokenizer: *Tokenizer) !Toc {
|
||||
const end_syntax_tag = try eatToken(tokenizer, Token.Id.TagContent);
|
||||
const end_tag_name = tokenizer.buffer[end_syntax_tag.start..end_syntax_tag.end];
|
||||
if (!mem.eql(u8, end_tag_name, "endsyntax")) {
|
||||
return parseError(tokenizer, end_syntax_tag, "invalid token inside syntax: {}", end_tag_name);
|
||||
return parseError(
|
||||
tokenizer,
|
||||
end_syntax_tag,
|
||||
"invalid token inside syntax: {}",
|
||||
.{end_tag_name},
|
||||
);
|
||||
}
|
||||
_ = try eatToken(tokenizer, Token.Id.BracketClose);
|
||||
try nodes.append(Node{ .Syntax = content_tok });
|
||||
} else {
|
||||
return parseError(tokenizer, tag_token, "unrecognized tag name: {}", tag_name);
|
||||
return parseError(tokenizer, tag_token, "unrecognized tag name: {}", .{tag_name});
|
||||
}
|
||||
},
|
||||
else => return parseError(tokenizer, token, "invalid token"),
|
||||
else => return parseError(tokenizer, token, "invalid token", .{}),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,7 +745,7 @@ fn termColor(allocator: *mem.Allocator, input: []const u8) ![]u8 {
|
||||
try out.write("</span>");
|
||||
}
|
||||
if (first_number != 0 or second_number != 0) {
|
||||
try out.print("<span class=\"t{}_{}\">", first_number, second_number);
|
||||
try out.print("<span class=\"t{}_{}\">", .{ first_number, second_number });
|
||||
open_span_count += 1;
|
||||
}
|
||||
},
|
||||
@@ -802,6 +818,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
.Keyword_resume,
|
||||
.Keyword_return,
|
||||
.Keyword_linksection,
|
||||
.Keyword_callconv,
|
||||
.Keyword_stdcallcc,
|
||||
.Keyword_struct,
|
||||
.Keyword_suspend,
|
||||
@@ -856,6 +873,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
|
||||
.LineComment,
|
||||
.DocComment,
|
||||
.ContainerDocComment,
|
||||
.ShebangLine,
|
||||
=> {
|
||||
try out.write("<span class=\"tok-comment\">");
|
||||
@@ -917,6 +935,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
.LBracket,
|
||||
.RBracket,
|
||||
.Period,
|
||||
.PeriodAsterisk,
|
||||
.Ellipsis2,
|
||||
.Ellipsis3,
|
||||
.Caret,
|
||||
@@ -952,14 +971,13 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: var, source_token: Tok
|
||||
.AngleBracketAngleBracketRight,
|
||||
.AngleBracketAngleBracketRightEqual,
|
||||
.Tilde,
|
||||
.BracketStarBracket,
|
||||
.BracketStarCBracket,
|
||||
=> try writeEscaped(out, src[token.start..token.end]),
|
||||
|
||||
.Invalid, .Invalid_ampersands => return parseError(
|
||||
docgen_tokenizer,
|
||||
source_token,
|
||||
"syntax error",
|
||||
.{},
|
||||
),
|
||||
}
|
||||
index = token.end;
|
||||
@@ -987,9 +1005,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
},
|
||||
Node.Link => |info| {
|
||||
if (!toc.urls.contains(info.url)) {
|
||||
return parseError(tokenizer, info.token, "url not found: {}", info.url);
|
||||
return parseError(tokenizer, info.token, "url not found: {}", .{info.url});
|
||||
}
|
||||
try out.print("<a href=\"#{}\">{}</a>", info.url, info.name);
|
||||
try out.print("<a href=\"#{}\">{}</a>", .{ info.url, info.name });
|
||||
},
|
||||
Node.Nav => {
|
||||
try out.write(toc.toc);
|
||||
@@ -1002,12 +1020,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
Node.HeaderOpen => |info| {
|
||||
try out.print(
|
||||
"<h{} id=\"{}\"><a href=\"#toc-{}\">{}</a> <a class=\"hdr\" href=\"#{}\">§</a></h{}>\n",
|
||||
info.n,
|
||||
info.url,
|
||||
info.url,
|
||||
info.name,
|
||||
info.url,
|
||||
info.n,
|
||||
.{ info.n, info.url, info.url, info.name, info.url, info.n },
|
||||
);
|
||||
},
|
||||
Node.SeeAlso => |items| {
|
||||
@@ -1015,9 +1028,9 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
for (items) |item| {
|
||||
const url = try urlize(allocator, item.name);
|
||||
if (!toc.urls.contains(url)) {
|
||||
return parseError(tokenizer, item.token, "url not found: {}", url);
|
||||
return parseError(tokenizer, item.token, "url not found: {}", .{url});
|
||||
}
|
||||
try out.print("<li><a href=\"#{}\">{}</a></li>\n", url, item.name);
|
||||
try out.print("<li><a href=\"#{}\">{}</a></li>\n", .{ url, item.name });
|
||||
}
|
||||
try out.write("</ul>\n");
|
||||
},
|
||||
@@ -1026,29 +1039,29 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
},
|
||||
Node.Code => |code| {
|
||||
code_progress_index += 1;
|
||||
warn("docgen example code {}/{}...", code_progress_index, tokenizer.code_node_count);
|
||||
warn("docgen example code {}/{}...", .{ code_progress_index, tokenizer.code_node_count });
|
||||
|
||||
const raw_source = tokenizer.buffer[code.source_token.start..code.source_token.end];
|
||||
const trimmed_raw_source = mem.trim(u8, raw_source, " \n");
|
||||
if (!code.is_inline) {
|
||||
try out.print("<p class=\"file\">{}.zig</p>", code.name);
|
||||
try out.print("<p class=\"file\">{}.zig</p>", .{code.name});
|
||||
}
|
||||
try out.write("<pre>");
|
||||
try tokenizeAndPrint(tokenizer, out, code.source_token);
|
||||
try out.write("</pre>");
|
||||
const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", code.name);
|
||||
const name_plus_ext = try std.fmt.allocPrint(allocator, "{}.zig", .{code.name});
|
||||
const tmp_source_file_name = try fs.path.join(
|
||||
allocator,
|
||||
[_][]const u8{ tmp_dir_name, name_plus_ext },
|
||||
&[_][]const u8{ tmp_dir_name, name_plus_ext },
|
||||
);
|
||||
try io.writeFile(tmp_source_file_name, trimmed_raw_source);
|
||||
|
||||
switch (code.id) {
|
||||
Code.Id.Exe => |expected_outcome| code_block: {
|
||||
const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, exe_ext);
|
||||
const name_plus_bin_ext = try std.fmt.allocPrint(allocator, "{}{}", .{ code.name, exe_ext });
|
||||
var build_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer build_args.deinit();
|
||||
try build_args.appendSlice([_][]const u8{
|
||||
try build_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"build-exe",
|
||||
tmp_source_file_name,
|
||||
@@ -1059,40 +1072,40 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
"--cache",
|
||||
"on",
|
||||
});
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", code.name);
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-exe {}.zig", .{code.name});
|
||||
switch (code.mode) {
|
||||
builtin.Mode.Debug => {},
|
||||
builtin.Mode.ReleaseSafe => {
|
||||
try build_args.append("--release-safe");
|
||||
try out.print(" --release-safe");
|
||||
try out.print(" --release-safe", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseFast => {
|
||||
try build_args.append("--release-fast");
|
||||
try out.print(" --release-fast");
|
||||
try out.print(" --release-fast", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseSmall => {
|
||||
try build_args.append("--release-small");
|
||||
try out.print(" --release-small");
|
||||
try out.print(" --release-small", .{});
|
||||
},
|
||||
}
|
||||
for (code.link_objects) |link_object| {
|
||||
const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", link_object, obj_ext);
|
||||
const name_with_ext = try std.fmt.allocPrint(allocator, "{}{}", .{ link_object, obj_ext });
|
||||
const full_path_object = try fs.path.join(
|
||||
allocator,
|
||||
[_][]const u8{ tmp_dir_name, name_with_ext },
|
||||
&[_][]const u8{ tmp_dir_name, name_with_ext },
|
||||
);
|
||||
try build_args.append("--object");
|
||||
try build_args.append(full_path_object);
|
||||
try out.print(" --object {}", name_with_ext);
|
||||
try out.print(" --object {}", .{name_with_ext});
|
||||
}
|
||||
if (code.link_libc) {
|
||||
try build_args.append("-lc");
|
||||
try out.print(" -lc");
|
||||
try out.print(" -lc", .{});
|
||||
}
|
||||
if (code.target_str) |triple| {
|
||||
try build_args.appendSlice([_][]const u8{ "-target", triple });
|
||||
try build_args.appendSlice(&[_][]const u8{ "-target", triple });
|
||||
if (!code.is_inline) {
|
||||
try out.print(" -target {}", triple);
|
||||
try out.print(" -target {}", .{triple});
|
||||
}
|
||||
}
|
||||
if (expected_outcome == .BuildFail) {
|
||||
@@ -1106,29 +1119,29 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
|
||||
for (build_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
warn("{}\nThe following command crashed:\n", result.stderr);
|
||||
warn("{}\nThe following command crashed:\n", .{result.stderr});
|
||||
for (build_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
|
||||
},
|
||||
}
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const colored_stderr = try termColor(allocator, escaped_stderr);
|
||||
try out.print("\n{}</code></pre>\n", colored_stderr);
|
||||
try out.print("\n{}</code></pre>\n", .{colored_stderr});
|
||||
break :code_block;
|
||||
}
|
||||
const exec_result = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
const exec_result = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});
|
||||
|
||||
if (code.target_str) |triple| {
|
||||
if (mem.startsWith(u8, triple, "wasm32") or
|
||||
@@ -1137,13 +1150,13 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
(builtin.os != .linux or builtin.arch != .x86_64))
|
||||
{
|
||||
// skip execution
|
||||
try out.print("</code></pre>\n");
|
||||
try out.print("</code></pre>\n", .{});
|
||||
break :code_block;
|
||||
}
|
||||
}
|
||||
|
||||
const path_to_exe = mem.trim(u8, exec_result.stdout, " \r\n");
|
||||
const run_args = [_][]const u8{path_to_exe};
|
||||
const run_args = &[_][]const u8{path_to_exe};
|
||||
|
||||
var exited_with_signal = false;
|
||||
|
||||
@@ -1152,12 +1165,12 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
|
||||
for (run_args) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
|
||||
}
|
||||
},
|
||||
.Signal => exited_with_signal = true,
|
||||
@@ -1165,7 +1178,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
}
|
||||
break :blk result;
|
||||
} else blk: {
|
||||
break :blk exec(allocator, &env_map, run_args) catch return parseError(tokenizer, code.source_token, "example crashed");
|
||||
break :blk exec(allocator, &env_map, run_args) catch return parseError(tokenizer, code.source_token, "example crashed", .{});
|
||||
};
|
||||
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
@@ -1174,57 +1187,57 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
const colored_stderr = try termColor(allocator, escaped_stderr);
|
||||
const colored_stdout = try termColor(allocator, escaped_stdout);
|
||||
|
||||
try out.print("\n$ ./{}\n{}{}", code.name, colored_stdout, colored_stderr);
|
||||
try out.print("\n$ ./{}\n{}{}", .{ code.name, colored_stdout, colored_stderr });
|
||||
if (exited_with_signal) {
|
||||
try out.print("(process terminated by signal)");
|
||||
try out.print("(process terminated by signal)", .{});
|
||||
}
|
||||
try out.print("</code></pre>\n");
|
||||
try out.print("</code></pre>\n", .{});
|
||||
},
|
||||
Code.Id.Test => {
|
||||
var test_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer test_args.deinit();
|
||||
|
||||
try test_args.appendSlice([_][]const u8{
|
||||
try test_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"test",
|
||||
tmp_source_file_name,
|
||||
"--cache",
|
||||
"on",
|
||||
});
|
||||
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
|
||||
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name});
|
||||
switch (code.mode) {
|
||||
builtin.Mode.Debug => {},
|
||||
builtin.Mode.ReleaseSafe => {
|
||||
try test_args.append("--release-safe");
|
||||
try out.print(" --release-safe");
|
||||
try out.print(" --release-safe", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseFast => {
|
||||
try test_args.append("--release-fast");
|
||||
try out.print(" --release-fast");
|
||||
try out.print(" --release-fast", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseSmall => {
|
||||
try test_args.append("--release-small");
|
||||
try out.print(" --release-small");
|
||||
try out.print(" --release-small", .{});
|
||||
},
|
||||
}
|
||||
if (code.link_libc) {
|
||||
try test_args.append("-lc");
|
||||
try out.print(" -lc");
|
||||
try out.print(" -lc", .{});
|
||||
}
|
||||
if (code.target_str) |triple| {
|
||||
try test_args.appendSlice([_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", triple);
|
||||
try test_args.appendSlice(&[_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", .{triple});
|
||||
}
|
||||
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
||||
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed", .{});
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const escaped_stdout = try escapeHtml(allocator, result.stdout);
|
||||
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
|
||||
try out.print("\n{}{}</code></pre>\n", .{ escaped_stderr, escaped_stdout });
|
||||
},
|
||||
Code.Id.TestError => |error_match| {
|
||||
var test_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer test_args.deinit();
|
||||
|
||||
try test_args.appendSlice([_][]const u8{
|
||||
try test_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"test",
|
||||
"--color",
|
||||
@@ -1233,57 +1246,57 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
"--output-dir",
|
||||
tmp_dir_name,
|
||||
});
|
||||
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", code.name);
|
||||
try out.print("<pre><code class=\"shell\">$ zig test {}.zig", .{code.name});
|
||||
switch (code.mode) {
|
||||
builtin.Mode.Debug => {},
|
||||
builtin.Mode.ReleaseSafe => {
|
||||
try test_args.append("--release-safe");
|
||||
try out.print(" --release-safe");
|
||||
try out.print(" --release-safe", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseFast => {
|
||||
try test_args.append("--release-fast");
|
||||
try out.print(" --release-fast");
|
||||
try out.print(" --release-fast", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseSmall => {
|
||||
try test_args.append("--release-small");
|
||||
try out.print(" --release-small");
|
||||
try out.print(" --release-small", .{});
|
||||
},
|
||||
}
|
||||
const result = try ChildProcess.exec(allocator, test_args.toSliceConst(), null, &env_map, max_doc_file_size);
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
|
||||
for (test_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example incorrectly compiled", .{});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
warn("{}\nThe following command crashed:\n", result.stderr);
|
||||
warn("{}\nThe following command crashed:\n", .{result.stderr});
|
||||
for (test_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
|
||||
},
|
||||
}
|
||||
if (mem.indexOf(u8, result.stderr, error_match) == null) {
|
||||
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected compile error");
|
||||
warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected compile error", .{});
|
||||
}
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const colored_stderr = try termColor(allocator, escaped_stderr);
|
||||
try out.print("\n{}</code></pre>\n", colored_stderr);
|
||||
try out.print("\n{}</code></pre>\n", .{colored_stderr});
|
||||
},
|
||||
|
||||
Code.Id.TestSafety => |error_match| {
|
||||
var test_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer test_args.deinit();
|
||||
|
||||
try test_args.appendSlice([_][]const u8{
|
||||
try test_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"test",
|
||||
tmp_source_file_name,
|
||||
@@ -1311,52 +1324,51 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
|
||||
for (test_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example test incorrectly succeeded");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example test incorrectly succeeded", .{});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
warn("{}\nThe following command crashed:\n", result.stderr);
|
||||
warn("{}\nThe following command crashed:\n", .{result.stderr});
|
||||
for (test_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
|
||||
},
|
||||
}
|
||||
if (mem.indexOf(u8, result.stderr, error_match) == null) {
|
||||
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message");
|
||||
warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message", .{});
|
||||
}
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const colored_stderr = try termColor(allocator, escaped_stderr);
|
||||
try out.print(
|
||||
"<pre><code class=\"shell\">$ zig test {}.zig{}\n{}</code></pre>\n",
|
||||
try out.print("<pre><code class=\"shell\">$ zig test {}.zig{}\n{}</code></pre>\n", .{
|
||||
code.name,
|
||||
mode_arg,
|
||||
colored_stderr,
|
||||
);
|
||||
});
|
||||
},
|
||||
Code.Id.Obj => |maybe_error_match| {
|
||||
const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", code.name, obj_ext);
|
||||
const name_plus_obj_ext = try std.fmt.allocPrint(allocator, "{}{}", .{ code.name, obj_ext });
|
||||
const tmp_obj_file_name = try fs.path.join(
|
||||
allocator,
|
||||
[_][]const u8{ tmp_dir_name, name_plus_obj_ext },
|
||||
&[_][]const u8{ tmp_dir_name, name_plus_obj_ext },
|
||||
);
|
||||
var build_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer build_args.deinit();
|
||||
|
||||
const name_plus_h_ext = try std.fmt.allocPrint(allocator, "{}.h", code.name);
|
||||
const name_plus_h_ext = try std.fmt.allocPrint(allocator, "{}.h", .{code.name});
|
||||
const output_h_file_name = try fs.path.join(
|
||||
allocator,
|
||||
[_][]const u8{ tmp_dir_name, name_plus_h_ext },
|
||||
&[_][]const u8{ tmp_dir_name, name_plus_h_ext },
|
||||
);
|
||||
|
||||
try build_args.appendSlice([_][]const u8{
|
||||
try build_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"build-obj",
|
||||
tmp_source_file_name,
|
||||
@@ -1369,7 +1381,7 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
});
|
||||
|
||||
if (!code.is_inline) {
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", code.name);
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-obj {}.zig", .{code.name});
|
||||
}
|
||||
|
||||
switch (code.mode) {
|
||||
@@ -1377,26 +1389,26 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
builtin.Mode.ReleaseSafe => {
|
||||
try build_args.append("--release-safe");
|
||||
if (!code.is_inline) {
|
||||
try out.print(" --release-safe");
|
||||
try out.print(" --release-safe", .{});
|
||||
}
|
||||
},
|
||||
builtin.Mode.ReleaseFast => {
|
||||
try build_args.append("--release-fast");
|
||||
if (!code.is_inline) {
|
||||
try out.print(" --release-fast");
|
||||
try out.print(" --release-fast", .{});
|
||||
}
|
||||
},
|
||||
builtin.Mode.ReleaseSmall => {
|
||||
try build_args.append("--release-small");
|
||||
if (!code.is_inline) {
|
||||
try out.print(" --release-small");
|
||||
try out.print(" --release-small", .{});
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (code.target_str) |triple| {
|
||||
try build_args.appendSlice([_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", triple);
|
||||
try build_args.appendSlice(&[_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", .{triple});
|
||||
}
|
||||
|
||||
if (maybe_error_match) |error_match| {
|
||||
@@ -1404,78 +1416,75 @@ fn genHtml(allocator: *mem.Allocator, tokenizer: *Tokenizer, toc: *Toc, out: var
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code == 0) {
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", result.stderr);
|
||||
warn("{}\nThe following command incorrectly succeeded:\n", .{result.stderr});
|
||||
for (build_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example build incorrectly succeeded");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example build incorrectly succeeded", .{});
|
||||
}
|
||||
},
|
||||
else => {
|
||||
warn("{}\nThe following command crashed:\n", result.stderr);
|
||||
warn("{}\nThe following command crashed:\n", .{result.stderr});
|
||||
for (build_args.toSliceConst()) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed");
|
||||
warn("\n", .{});
|
||||
return parseError(tokenizer, code.source_token, "example compile crashed", .{});
|
||||
},
|
||||
}
|
||||
if (mem.indexOf(u8, result.stderr, error_match) == null) {
|
||||
warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected compile error message");
|
||||
warn("{}\nExpected to find '{}' in stderr", .{ result.stderr, error_match });
|
||||
return parseError(tokenizer, code.source_token, "example did not have expected compile error message", .{});
|
||||
}
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const colored_stderr = try termColor(allocator, escaped_stderr);
|
||||
try out.print("\n{}\n", colored_stderr);
|
||||
if (!code.is_inline) {
|
||||
try out.print("</code></pre>\n");
|
||||
}
|
||||
try out.print("\n{}", .{colored_stderr});
|
||||
} else {
|
||||
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile");
|
||||
_ = exec(allocator, &env_map, build_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "example failed to compile", .{});
|
||||
}
|
||||
if (!code.is_inline) {
|
||||
try out.print("</code></pre>\n");
|
||||
try out.print("</code></pre>\n", .{});
|
||||
}
|
||||
},
|
||||
Code.Id.Lib => {
|
||||
var test_args = std.ArrayList([]const u8).init(allocator);
|
||||
defer test_args.deinit();
|
||||
|
||||
try test_args.appendSlice([_][]const u8{
|
||||
try test_args.appendSlice(&[_][]const u8{
|
||||
zig_exe,
|
||||
"build-lib",
|
||||
tmp_source_file_name,
|
||||
"--output-dir",
|
||||
tmp_dir_name,
|
||||
});
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-lib {}.zig", code.name);
|
||||
try out.print("<pre><code class=\"shell\">$ zig build-lib {}.zig", .{code.name});
|
||||
switch (code.mode) {
|
||||
builtin.Mode.Debug => {},
|
||||
builtin.Mode.ReleaseSafe => {
|
||||
try test_args.append("--release-safe");
|
||||
try out.print(" --release-safe");
|
||||
try out.print(" --release-safe", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseFast => {
|
||||
try test_args.append("--release-fast");
|
||||
try out.print(" --release-fast");
|
||||
try out.print(" --release-fast", .{});
|
||||
},
|
||||
builtin.Mode.ReleaseSmall => {
|
||||
try test_args.append("--release-small");
|
||||
try out.print(" --release-small");
|
||||
try out.print(" --release-small", .{});
|
||||
},
|
||||
}
|
||||
if (code.target_str) |triple| {
|
||||
try test_args.appendSlice([_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", triple);
|
||||
try test_args.appendSlice(&[_][]const u8{ "-target", triple });
|
||||
try out.print(" -target {}", .{triple});
|
||||
}
|
||||
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed");
|
||||
const result = exec(allocator, &env_map, test_args.toSliceConst()) catch return parseError(tokenizer, code.source_token, "test failed", .{});
|
||||
const escaped_stderr = try escapeHtml(allocator, result.stderr);
|
||||
const escaped_stdout = try escapeHtml(allocator, result.stdout);
|
||||
try out.print("\n{}{}</code></pre>\n", escaped_stderr, escaped_stdout);
|
||||
try out.print("\n{}{}</code></pre>\n", .{ escaped_stderr, escaped_stdout });
|
||||
},
|
||||
}
|
||||
warn("OK\n");
|
||||
warn("OK\n", .{});
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1486,20 +1495,20 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
|
||||
switch (result.term) {
|
||||
.Exited => |exit_code| {
|
||||
if (exit_code != 0) {
|
||||
warn("{}\nThe following command exited with code {}:\n", result.stderr, exit_code);
|
||||
warn("{}\nThe following command exited with code {}:\n", .{ result.stderr, exit_code });
|
||||
for (args) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
warn("\n", .{});
|
||||
return error.ChildExitError;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
warn("{}\nThe following command crashed:\n", result.stderr);
|
||||
warn("{}\nThe following command crashed:\n", .{result.stderr});
|
||||
for (args) |arg|
|
||||
warn("{} ", arg)
|
||||
warn("{} ", .{arg})
|
||||
else
|
||||
warn("\n");
|
||||
warn("\n", .{});
|
||||
return error.ChildCrashed;
|
||||
},
|
||||
}
|
||||
@@ -1507,7 +1516,7 @@ fn exec(allocator: *mem.Allocator, env_map: *std.BufMap, args: []const []const u
|
||||
}
|
||||
|
||||
fn getBuiltinCode(allocator: *mem.Allocator, env_map: *std.BufMap, zig_exe: []const u8) ![]const u8 {
|
||||
const result = try exec(allocator, env_map, [_][]const u8{
|
||||
const result = try exec(allocator, env_map, &[_][]const u8{
|
||||
zig_exe,
|
||||
"builtin",
|
||||
});
|
||||
|
||||
+782
-664
@@ -1,13 +1,13 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||
<title>Documentation - The Zig Programming Language</title>
|
||||
<link rel="icon" href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNSAxMCIgZmlsbD0iI2Y3YTQxZCI+PHBhdGggZD0iTTAsMSBIMy41IFYzIEgyIFY3IEgzLjY4MiBMMS44ODEsOSBIMCBaIE0xNSw5IEgxMS41IFY3IEgxMyBWMyBIMTEuMzE4IEwxMy4xMTksMSBIMTUgWiBNNCwxIEg5LjkxMiBMMTMuMzI4LDAuMDIxIEw3LjA0NSw3IEgxMSBWOSBINS4wODggTDEuNjcyLDkuOTc5IEw3Ljk1NSwzIEg0IFoiLz48L3N2Zz4="/>
|
||||
<style type="text/css">
|
||||
<link rel="icon" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAgklEQVR4AWMYWuD7EllJIM4G4g4g5oIJ/odhOJ8wToOxSTXgNxDHoeiBMfA4+wGShjyYOCkG/IGqWQziEzYAoUAeiF9D5U+DxEg14DRU7jWIT5IBIOdCxf+A+CQZAAoopEB7QJwBCBwHiip8UYmRdrAlDpIMgApwQZNnNii5Dq0MBgCxxycBnwEd+wAAAABJRU5ErkJggg=="/>
|
||||
<style>
|
||||
body{
|
||||
font-family: system-ui, -apple-system, Roboto, "Segoe UI", sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
a:not(:hover) {
|
||||
text-decoration: none;
|
||||
@@ -81,11 +81,35 @@
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#main-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
#contents-wrapper {
|
||||
flex-grow: 1;
|
||||
padding: 0 2em;
|
||||
}
|
||||
|
||||
#contents {
|
||||
max-width: 60em;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#index {
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 1025px) {
|
||||
#main-wrapper {
|
||||
flex-direction: row;
|
||||
}
|
||||
#contents-wrapper, #index {
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
|
||||
h1 a, h2 a, h3 a, h4 a, h5 a {
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
@@ -156,24 +180,31 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://ziglang.org/documentation/0.1.1">0.1.1</a> |
|
||||
<a href="https://ziglang.org/documentation/0.2.0">0.2.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.3.0">0.3.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.4.0">0.4.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.5.0">0.5.0</a> |
|
||||
master
|
||||
<div id="contents">
|
||||
<div id="main-wrapper">
|
||||
<div id="index">
|
||||
<a href="https://ziglang.org/documentation/0.1.1">0.1.1</a> |
|
||||
<a href="https://ziglang.org/documentation/0.2.0">0.2.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.3.0">0.3.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.4.0">0.4.0</a> |
|
||||
<a href="https://ziglang.org/documentation/0.5.0">0.5.0</a> |
|
||||
master
|
||||
<h1>Index</h1>
|
||||
{#nav#}
|
||||
</div>
|
||||
<div id="contents-wrapper"><div id="contents">
|
||||
{#header_open|Introduction#}
|
||||
<p>
|
||||
Zig is a general-purpose programming language designed for <strong>robustness</strong>,
|
||||
<strong>optimality</strong>, and <strong>maintainability</strong>.
|
||||
Zig is a general-purpose programming language and toolchain for maintaining
|
||||
<strong>robust</strong>, <strong>optimal</strong>, and <strong>reusable</strong> software.
|
||||
</p>
|
||||
<ul>
|
||||
<li><strong>Robust</strong> - behavior is correct even for edge cases such as out of memory.</li>
|
||||
<li><strong>Optimal</strong> - write programs the best way they can behave and perform.</li>
|
||||
<li><strong>Maintainable</strong> - precisely communicate intent to the compiler and other programmers.
|
||||
The language imposes a low overhead to reading code and is resilient to changing requirements
|
||||
and environments.</li>
|
||||
<li><strong>Reusable</strong> - the same code works in many environments which have different
|
||||
constraints.</li>
|
||||
<li><strong>Maintainable</strong> - precisely communicate intent to the compiler and
|
||||
other programmers. The language imposes a low overhead to reading code and is
|
||||
resilient to changing requirements and environments.</li>
|
||||
</ul>
|
||||
<p>
|
||||
Often the most efficient way to learn something new is to see examples, so
|
||||
@@ -193,21 +224,14 @@
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Index#}
|
||||
{#nav#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Hello World#}
|
||||
|
||||
{#code_begin|exe|hello#}
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
// If this program is run without stdout attached, exit with an error.
|
||||
const stdout_file = try std.io.getStdOut();
|
||||
// If this program encounters pipe failure when printing to stdout, exit
|
||||
// with an error.
|
||||
try stdout_file.write("Hello, world!\n");
|
||||
const stdout = &std.io.getStdOut().outStream().stream;
|
||||
try stdout.print("Hello, {}!\n", .{"world"});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -219,7 +243,7 @@ pub fn main() !void {
|
||||
const warn = @import("std").debug.warn;
|
||||
|
||||
pub fn main() void {
|
||||
warn("Hello, world!\n");
|
||||
warn("Hello, world!\n", .{});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -291,41 +315,50 @@ const assert = std.debug.assert;
|
||||
pub fn main() void {
|
||||
// integers
|
||||
const one_plus_one: i32 = 1 + 1;
|
||||
warn("1 + 1 = {}\n", one_plus_one);
|
||||
warn("1 + 1 = {}\n", .{one_plus_one});
|
||||
|
||||
// floats
|
||||
const seven_div_three: f32 = 7.0 / 3.0;
|
||||
warn("7.0 / 3.0 = {}\n", seven_div_three);
|
||||
warn("7.0 / 3.0 = {}\n", .{seven_div_three});
|
||||
|
||||
// boolean
|
||||
warn("{}\n{}\n{}\n",
|
||||
warn("{}\n{}\n{}\n", .{
|
||||
true and false,
|
||||
true or false,
|
||||
!true);
|
||||
!true,
|
||||
});
|
||||
|
||||
// optional
|
||||
var optional_value: ?[]const u8 = null;
|
||||
assert(optional_value == null);
|
||||
|
||||
warn("\noptional 1\ntype: {}\nvalue: {}\n",
|
||||
@typeName(@typeOf(optional_value)), optional_value);
|
||||
warn("\noptional 1\ntype: {}\nvalue: {}\n", .{
|
||||
@typeName(@TypeOf(optional_value)),
|
||||
optional_value,
|
||||
});
|
||||
|
||||
optional_value = "hi";
|
||||
assert(optional_value != null);
|
||||
|
||||
warn("\noptional 2\ntype: {}\nvalue: {}\n",
|
||||
@typeName(@typeOf(optional_value)), optional_value);
|
||||
warn("\noptional 2\ntype: {}\nvalue: {}\n", .{
|
||||
@typeName(@TypeOf(optional_value)),
|
||||
optional_value,
|
||||
});
|
||||
|
||||
// error union
|
||||
var number_or_error: anyerror!i32 = error.ArgNotFound;
|
||||
|
||||
warn("\nerror union 1\ntype: {}\nvalue: {}\n",
|
||||
@typeName(@typeOf(number_or_error)), number_or_error);
|
||||
warn("\nerror union 1\ntype: {}\nvalue: {}\n", .{
|
||||
@typeName(@TypeOf(number_or_error)),
|
||||
number_or_error,
|
||||
});
|
||||
|
||||
number_or_error = 1234;
|
||||
|
||||
warn("\nerror union 2\ntype: {}\nvalue: {}\n",
|
||||
@typeName(@typeOf(number_or_error)), number_or_error);
|
||||
warn("\nerror union 2\ntype: {}\nvalue: {}\n", .{
|
||||
@typeName(@TypeOf(number_or_error)),
|
||||
number_or_error,
|
||||
});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_open|Primitive Types#}
|
||||
@@ -513,7 +546,7 @@ pub fn main() void {
|
||||
</div>
|
||||
<p>
|
||||
In addition to the integer types above, arbitrary bit-width integers can be referenced by using
|
||||
an identifier of <code>i</code> or </code>u</code> followed by digits. For example, the identifier
|
||||
an identifier of <code>i</code> or <code>u</code> followed by digits. For example, the identifier
|
||||
{#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
|
||||
integer type is {#syntax#}65535{#endsyntax#}.
|
||||
</p>
|
||||
@@ -548,32 +581,31 @@ pub fn main() void {
|
||||
{#header_close#}
|
||||
{#header_open|String Literals and Character Literals#}
|
||||
<p>
|
||||
String literals are UTF-8 encoded byte arrays.
|
||||
String literals are single-item constant {#link|Pointers#} to null-terminated UTF-8 encoded byte arrays.
|
||||
The type of string literals encodes both the length, and the fact that they are null-terminated,
|
||||
and thus they can be {#link|coerced|Type Coercion#} to both {#link|Slices#} and
|
||||
{#link|Null-Terminated Pointers|Sentinel-Terminated Pointers#}.
|
||||
Dereferencing string literals converts them to {#link|Arrays#}.
|
||||
</p>
|
||||
<p>
|
||||
Character literals have type {#syntax#}comptime_int{#endsyntax#}, the same as
|
||||
{#link|Integer Literals#}. All {#link|Escape Sequences#} are valid in both string literals
|
||||
and character literals. Once https://github.com/ziglang/zig/issues/2097 is implemented,
|
||||
character literals will be allowed to have a single UTF-8 encoded codepoint.
|
||||
and character literals.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const assert = @import("std").debug.assert;
|
||||
const mem = @import("std").mem;
|
||||
|
||||
test "string literals" {
|
||||
// In Zig a string literal is an array of bytes.
|
||||
const normal_bytes = "hello";
|
||||
assert(@typeOf(normal_bytes) == [5]u8);
|
||||
assert(normal_bytes.len == 5);
|
||||
assert(normal_bytes[1] == 'e');
|
||||
const bytes = "hello";
|
||||
assert(@TypeOf(bytes) == *const [5:0]u8);
|
||||
assert(bytes.len == 5);
|
||||
assert(bytes[1] == 'e');
|
||||
assert(bytes[5] == 0);
|
||||
assert('e' == '\x65');
|
||||
assert('\u{1f4a9}' == 128169);
|
||||
assert('💯' == 128175);
|
||||
assert(mem.eql(u8, "hello", "h\x65llo"));
|
||||
|
||||
// A C string literal is a null terminated pointer.
|
||||
const null_terminated_bytes = c"hello";
|
||||
assert(@typeOf(null_terminated_bytes) == [*]const u8);
|
||||
assert(null_terminated_bytes[5] == 0);
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|Arrays|Zig Test|Source Encoding#}
|
||||
@@ -643,23 +675,6 @@ const hello_world_in_c =
|
||||
\\}
|
||||
;
|
||||
{#code_end#}
|
||||
<p>
|
||||
For a multiline C string literal, prepend <code>c</code> to each {#syntax#}\\{#endsyntax#}:
|
||||
</p>
|
||||
{#code_begin|syntax#}
|
||||
const c_string_literal =
|
||||
c\\#include <stdio.h>
|
||||
c\\
|
||||
c\\int main(int argc, char **argv) {
|
||||
c\\ printf("hello world\n");
|
||||
c\\ return 0;
|
||||
c\\}
|
||||
;
|
||||
{#code_end#}
|
||||
<p>
|
||||
In this example the variable {#syntax#}c_string_literal{#endsyntax#} has type {#syntax#}[*]const u8{#endsyntax#} and
|
||||
has a terminating null byte.
|
||||
</p>
|
||||
{#see_also|@embedFile#}
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
@@ -713,7 +728,7 @@ test "init with undefined" {
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
{#syntax#}undefined{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to any type.
|
||||
{#syntax#}undefined{#endsyntax#} can be {#link|coerced|Type Coercion#} to any type.
|
||||
Once this happens, it is no longer possible to detect that the value is {#syntax#}undefined{#endsyntax#}.
|
||||
{#syntax#}undefined{#endsyntax#} means the value could be anything, even something that is nonsense
|
||||
according to the type. Translated into English, {#syntax#}undefined{#endsyntax#} means "Not a meaningful
|
||||
@@ -898,7 +913,7 @@ fn divide(a: i32, b: i32) i32 {
|
||||
</p>
|
||||
<p>
|
||||
Zig supports arbitrary bit-width integers, referenced by using
|
||||
an identifier of <code>i</code> or </code>u</code> followed by digits. For example, the identifier
|
||||
an identifier of <code>i</code> or <code>u</code> followed by digits. For example, the identifier
|
||||
{#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
|
||||
integer type is {#syntax#}65535{#endsyntax#}.
|
||||
</p>
|
||||
@@ -921,7 +936,7 @@ fn divide(a: i32, b: i32) i32 {
|
||||
{#syntax#}f128{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
Float literals {#link|implicitly cast|Implicit Casts#} to any floating point type,
|
||||
Float literals {#link|coerce|Type Coercion#} to any floating point type,
|
||||
and to any {#link|integer|Integers#} type when there is no fractional component.
|
||||
</p>
|
||||
{#code_begin|syntax#}
|
||||
@@ -951,7 +966,7 @@ const nan = std.math.nan(f128);
|
||||
{#code_begin|obj|foo#}
|
||||
{#code_release_fast#}
|
||||
const builtin = @import("builtin");
|
||||
const big = f64(1 << 40);
|
||||
const big = @as(f64, 1 << 40);
|
||||
|
||||
export fn foo_strict(x: f64) f64 {
|
||||
return x + big - big;
|
||||
@@ -974,8 +989,8 @@ extern fn foo_optimized(x: f64) f64;
|
||||
|
||||
pub fn main() void {
|
||||
const x = 0.001;
|
||||
warn("optimized = {}\n", foo_optimized(x));
|
||||
warn("strict = {}\n", foo_strict(x));
|
||||
warn("optimized = {}\n", .{foo_optimized(x)});
|
||||
warn("strict = {}\n", .{foo_strict(x)});
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|@setFloatMode|Division by Zero#}
|
||||
@@ -1039,7 +1054,7 @@ a +%= b{#endsyntax#}</pre></td>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<pre>{#syntax#}u32(std.math.maxInt(u32)) +% 1 == 0{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@as(u32, std.math.maxInt(u32)) +% 1 == 0{#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1078,7 +1093,7 @@ a -%= b{#endsyntax#}</pre></td>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<pre>{#syntax#}u32(0) -% 1 == std.math.maxInt(u32){#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@as(u32, 0) -% 1 == std.math.maxInt(u32){#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1113,7 +1128,7 @@ a -%= b{#endsyntax#}</pre></td>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<pre>{#syntax#}-%i32(std.math.minInt(i32)) == std.math.minInt(i32){#endsyntax#}</pre>
|
||||
<pre>{#syntax#}-%@as(i32, std.math.minInt(i32)) == std.math.minInt(i32){#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1152,7 +1167,7 @@ a *%= b{#endsyntax#}</pre></td>
|
||||
</ul>
|
||||
</td>
|
||||
<td>
|
||||
<pre>{#syntax#}u8(200) *% 2 == 144{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@as(u8, 200) *% 2 == 144{#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1304,7 +1319,7 @@ a ^= b{#endsyntax#}</pre></td>
|
||||
Bitwise NOT.
|
||||
</td>
|
||||
<td>
|
||||
<pre>{#syntax#}~u8(0b10101111) == 0b01010000{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}~@as(u8, 0b10101111) == 0b01010000{#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1538,7 +1553,7 @@ value == null{#endsyntax#}</pre>
|
||||
const array1 = [_]u32{1,2};
|
||||
const array2 = [_]u32{3,4};
|
||||
const together = array1 ++ array2;
|
||||
mem.eql(u32, together, [_]u32{1,2,3,4}){#endsyntax#}</pre>
|
||||
mem.eql(u32, together, &[_]u32{1,2,3,4}){#endsyntax#}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -1640,12 +1655,11 @@ comptime {
|
||||
assert(message.len == 5);
|
||||
}
|
||||
|
||||
// a string literal is an array literal
|
||||
// A string literal is a pointer to an array literal.
|
||||
const same_message = "hello";
|
||||
|
||||
comptime {
|
||||
assert(mem.eql(u8, message, same_message));
|
||||
assert(@typeOf(message) == @typeOf(same_message));
|
||||
assert(mem.eql(u8, &message, same_message));
|
||||
}
|
||||
|
||||
test "iterate over an array" {
|
||||
@@ -1653,7 +1667,7 @@ test "iterate over an array" {
|
||||
for (message) |byte| {
|
||||
sum += byte;
|
||||
}
|
||||
assert(sum == usize('h') + usize('e') + usize('l') * 2 + usize('o'));
|
||||
assert(sum == 'h' + 'e' + 'l' * 2 + 'o');
|
||||
}
|
||||
|
||||
// modifiable array
|
||||
@@ -1673,7 +1687,7 @@ const part_one = [_]i32{ 1, 2, 3, 4 };
|
||||
const part_two = [_]i32{ 5, 6, 7, 8 };
|
||||
const all_of_it = part_one ++ part_two;
|
||||
comptime {
|
||||
assert(mem.eql(i32, all_of_it, [_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }));
|
||||
assert(mem.eql(i32, &all_of_it, &[_]i32{ 1, 2, 3, 4, 5, 6, 7, 8 }));
|
||||
}
|
||||
|
||||
// remember that string literals are arrays
|
||||
@@ -1735,6 +1749,43 @@ test "array initialization with function calls" {
|
||||
{#code_end#}
|
||||
{#see_also|for|Slices#}
|
||||
|
||||
{#header_open|Anonymous List Literals#}
|
||||
<p>Similar to {#link|Enum Literals#} and {#link|Anonymous Struct Literals#}
|
||||
the type can be omitted from array literals:</p>
|
||||
{#code_begin|test|anon_list#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "anonymous list literal syntax" {
|
||||
var array: [4]u8 = .{11, 22, 33, 44};
|
||||
assert(array[0] == 11);
|
||||
assert(array[1] == 22);
|
||||
assert(array[2] == 33);
|
||||
assert(array[3] == 44);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
If there is no type in the result location then an anonymous list literal actually
|
||||
turns into a {#link|struct#} with numbered field names:
|
||||
</p>
|
||||
{#code_begin|test|infer_list_literal#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "fully anonymous list literal" {
|
||||
dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
|
||||
}
|
||||
|
||||
fn dump(args: var) void {
|
||||
assert(args.@"0" == 1234);
|
||||
assert(args.@"1" == 12.34);
|
||||
assert(args.@"2");
|
||||
assert(args.@"3"[0] == 'h');
|
||||
assert(args.@"3"[1] == 'i');
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Multidimensional Arrays#}
|
||||
<p>
|
||||
Mutlidimensional arrays can be created by nesting arrays:
|
||||
@@ -1764,6 +1815,26 @@ test "multidimensional arrays" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Sentinel-Terminated Arrays#}
|
||||
<p>
|
||||
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#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "null terminated array" {
|
||||
const array = [_:0]u8 {1, 2, 3, 4};
|
||||
|
||||
assert(@TypeOf(array) == [4:0]u8);
|
||||
assert(array.len == 4);
|
||||
assert(array[4] == 0);
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Slices#}
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Vectors#}
|
||||
@@ -1840,12 +1911,12 @@ test "address of syntax" {
|
||||
assert(x_ptr.* == 1234);
|
||||
|
||||
// When you get the address of a const variable, you get a const pointer to a single item.
|
||||
assert(@typeOf(x_ptr) == *const i32);
|
||||
assert(@TypeOf(x_ptr) == *const i32);
|
||||
|
||||
// If you want to mutate the value, you'd need an address of a mutable variable:
|
||||
var y: i32 = 5678;
|
||||
const y_ptr = &y;
|
||||
assert(@typeOf(y_ptr) == *i32);
|
||||
assert(@TypeOf(y_ptr) == *i32);
|
||||
y_ptr.* += 1;
|
||||
assert(y_ptr.* == 5679);
|
||||
}
|
||||
@@ -1856,7 +1927,7 @@ test "pointer array access" {
|
||||
// does not support pointer arithmetic.
|
||||
var array = [_]u8{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
const ptr = &array[2];
|
||||
assert(@typeOf(ptr) == *u8);
|
||||
assert(@TypeOf(ptr) == *u8);
|
||||
|
||||
assert(array[2] == 3);
|
||||
ptr.* += 1;
|
||||
@@ -1864,7 +1935,7 @@ test "pointer array access" {
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
In Zig, we prefer slices over pointers to null-terminated arrays.
|
||||
In Zig, we generally prefer {#link|Slices#} rather than {#link|Sentinel-Terminated Pointers#}.
|
||||
You can turn an array or pointer into a slice using slice syntax.
|
||||
</p>
|
||||
<p>
|
||||
@@ -1906,10 +1977,10 @@ test "comptime pointers" {
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "@ptrToInt and @intToPtr" {
|
||||
const ptr = @intToPtr(*i32, 0xdeadbeef);
|
||||
const ptr = @intToPtr(*i32, 0xdeadbee0);
|
||||
const addr = @ptrToInt(ptr);
|
||||
assert(@typeOf(addr) == usize);
|
||||
assert(addr == 0xdeadbeef);
|
||||
assert(@TypeOf(addr) == usize);
|
||||
assert(addr == 0xdeadbee0);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>Zig is able to preserve memory addresses in comptime code, as long as
|
||||
@@ -1921,10 +1992,10 @@ test "comptime @intToPtr" {
|
||||
comptime {
|
||||
// Zig is able to do this at compile-time, as long as
|
||||
// ptr is never dereferenced.
|
||||
const ptr = @intToPtr(*i32, 0xdeadbeef);
|
||||
const ptr = @intToPtr(*i32, 0xdeadbee0);
|
||||
const addr = @ptrToInt(ptr);
|
||||
assert(@typeOf(addr) == usize);
|
||||
assert(addr == 0xdeadbeef);
|
||||
assert(@TypeOf(addr) == usize);
|
||||
assert(addr == 0xdeadbee0);
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -1939,7 +2010,7 @@ const assert = @import("std").debug.assert;
|
||||
|
||||
test "volatile" {
|
||||
const mmio_ptr = @intToPtr(*volatile u8, 0x12345678);
|
||||
assert(@typeOf(mmio_ptr) == *volatile u8);
|
||||
assert(@TypeOf(mmio_ptr) == *volatile u8);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -1996,15 +2067,15 @@ const builtin = @import("builtin");
|
||||
|
||||
test "variable alignment" {
|
||||
var x: i32 = 1234;
|
||||
const align_of_i32 = @alignOf(@typeOf(x));
|
||||
assert(@typeOf(&x) == *i32);
|
||||
const align_of_i32 = @alignOf(@TypeOf(x));
|
||||
assert(@TypeOf(&x) == *i32);
|
||||
assert(*i32 == *align(align_of_i32) i32);
|
||||
if (builtin.arch == builtin.Arch.x86_64) {
|
||||
assert((*i32).alignment == 4);
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
<p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|implicitly cast|Implicit Casts#} to a
|
||||
<p>In the same way that a {#syntax#}*i32{#endsyntax#} can be {#link|coerced|Type Coercion#} to a
|
||||
{#syntax#}*const i32{#endsyntax#}, a pointer with a larger alignment can be implicitly
|
||||
cast to a pointer with a smaller alignment, but not vice versa.
|
||||
</p>
|
||||
@@ -2018,10 +2089,10 @@ const assert = @import("std").debug.assert;
|
||||
var foo: u8 align(4) = 100;
|
||||
|
||||
test "global variable alignment" {
|
||||
assert(@typeOf(&foo).alignment == 4);
|
||||
assert(@typeOf(&foo) == *align(4) u8);
|
||||
const slice = (*[1]u8)(&foo)[0..];
|
||||
assert(@typeOf(slice) == []align(4) u8);
|
||||
assert(@TypeOf(&foo).alignment == 4);
|
||||
assert(@TypeOf(&foo) == *align(4) u8);
|
||||
const slice = @as(*[1]u8, &foo)[0..];
|
||||
assert(@TypeOf(slice) == []align(4) u8);
|
||||
}
|
||||
|
||||
fn derp() align(@sizeOf(usize) * 2) i32 { return 1234; }
|
||||
@@ -2030,8 +2101,8 @@ fn noop4() align(4) void {}
|
||||
|
||||
test "function alignment" {
|
||||
assert(derp() == 1234);
|
||||
assert(@typeOf(noop1) == fn() align(1) void);
|
||||
assert(@typeOf(noop4) == fn() align(4) void);
|
||||
assert(@TypeOf(noop1) == fn() align(1) void);
|
||||
assert(@TypeOf(noop4) == fn() align(4) void);
|
||||
noop1();
|
||||
noop4();
|
||||
}
|
||||
@@ -2062,8 +2133,10 @@ fn foo(bytes: []u8) u32 {
|
||||
<p>
|
||||
This pointer attribute allows a pointer to have address zero. This is only ever needed on the
|
||||
freestanding OS target, where the address zero is mappable. If you want to represent null pointers, use
|
||||
{#link|Optional Pointers#} instead. In this code example, if the pointer did not have the
|
||||
{#syntax#}allowzero{#endsyntax#} attribute, this would be a {#link|Pointer Cast Invalid Null#} panic:
|
||||
{#link|Optional Pointers#} instead. {#link|Optional Pointers#} with {#syntax#}allowzero{#endsyntax#}
|
||||
are not the same size as pointers. In this code example, if the pointer
|
||||
did not have the {#syntax#}allowzero{#endsyntax#} attribute, this would be a
|
||||
{#link|Pointer Cast Invalid Null#} panic:
|
||||
</p>
|
||||
{#code_begin|test|allowzero#}
|
||||
const std = @import("std");
|
||||
@@ -2076,6 +2149,30 @@ test "allowzero" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Sentinel-Terminated Pointers#}
|
||||
<p>
|
||||
The syntax {#syntax#}[*:x]T{#endsyntax#} describes a pointer that
|
||||
has a length determined by a sentinel value. This provides protection
|
||||
against buffer overflow and overreads.
|
||||
</p>
|
||||
{#code_begin|exe_build_err#}
|
||||
{#link_libc#}
|
||||
const std = @import("std");
|
||||
|
||||
// This is also available as `std.c.printf`.
|
||||
pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
_ = printf("Hello, world!\n"); // OK
|
||||
|
||||
const msg = "Hello, world!\n";
|
||||
const non_null_terminated_msg: [msg.len]u8 = msg.*;
|
||||
_ = printf(&non_null_terminated_msg);
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|Sentinel-Terminated Slices|Sentinel-Terminated Arrays#}
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Slices#}
|
||||
@@ -2094,8 +2191,8 @@ test "basic slices" {
|
||||
|
||||
// Using the address-of operator on a slice gives a pointer to a single
|
||||
// item, while using the `ptr` field gives an unknown length pointer.
|
||||
assert(@typeOf(slice.ptr) == [*]i32);
|
||||
assert(@typeOf(&slice[0]) == *i32);
|
||||
assert(@TypeOf(slice.ptr) == [*]i32);
|
||||
assert(@TypeOf(&slice[0]) == *i32);
|
||||
assert(@ptrToInt(slice.ptr) == @ptrToInt(&slice[0]));
|
||||
|
||||
// Slices have array bounds checking. If you try to access something out
|
||||
@@ -2115,7 +2212,7 @@ const fmt = @import("std").fmt;
|
||||
test "using slices for strings" {
|
||||
// Zig has no concept of strings. String literals are arrays of u8, and
|
||||
// in general the string type is []u8 (slice of u8).
|
||||
// Here we implicitly cast [5]u8 to []const u8
|
||||
// Here we coerce [5]u8 to []const u8
|
||||
const hello: []const u8 = "hello";
|
||||
const world: []const u8 = "世界";
|
||||
|
||||
@@ -2123,7 +2220,7 @@ test "using slices for strings" {
|
||||
// You can use slice syntax on an array to convert an array into a slice.
|
||||
const all_together_slice = all_together[0..];
|
||||
// String concatenation example.
|
||||
const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", hello, world);
|
||||
const hello_world = try fmt.bufPrint(all_together_slice, "{} {}", .{hello, world});
|
||||
|
||||
// Generally, you can use UTF-8 and not worry about whether something is a
|
||||
// string. If you don't need to deal with individual characters, no need
|
||||
@@ -2140,7 +2237,7 @@ test "slice pointer" {
|
||||
slice[2] = 3;
|
||||
assert(slice[2] == 3);
|
||||
// The slice is mutable because we sliced a mutable pointer.
|
||||
assert(@typeOf(slice) == []u8);
|
||||
assert(@TypeOf(slice) == []u8);
|
||||
|
||||
// You can also slice a slice:
|
||||
const slice2 = slice[2..3];
|
||||
@@ -2159,7 +2256,29 @@ test "slice widening" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|Pointers|for|Arrays#}
|
||||
|
||||
{#header_open|Sentinel-Terminated Slices#}
|
||||
<p>
|
||||
The syntax {#syntax#}[:x]T{#endsyntax#} is a slice which has a runtime known length
|
||||
and also guarantees a sentinel value at the element indexed by the length. The type does not
|
||||
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#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "null terminated slice" {
|
||||
const slice: [:0]const u8 = "hello";
|
||||
|
||||
assert(slice.len == 5);
|
||||
assert(slice[5] == 0);
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|Sentinel-Terminated Pointers|Sentinel-Terminated Arrays#}
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|struct#}
|
||||
{#code_begin|test|structs#}
|
||||
// Declare a struct.
|
||||
@@ -2527,7 +2646,8 @@ test "overaligned pointer to packed struct" {
|
||||
Don't worry, there will be a good solution for this use case in zig.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|struct Naming#}
|
||||
|
||||
{#header_open|Struct Naming#}
|
||||
<p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p>
|
||||
<ul>
|
||||
<li>If the struct is in the initialization expression of a variable, it gets named after
|
||||
@@ -2541,9 +2661,9 @@ const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
const Foo = struct {};
|
||||
std.debug.warn("variable: {}\n", @typeName(Foo));
|
||||
std.debug.warn("anonymous: {}\n", @typeName(struct {}));
|
||||
std.debug.warn("function: {}\n", @typeName(List(i32)));
|
||||
std.debug.warn("variable: {}\n", .{@typeName(Foo)});
|
||||
std.debug.warn("anonymous: {}\n", .{@typeName(struct {})});
|
||||
std.debug.warn("function: {}\n", .{@typeName(List(i32))});
|
||||
}
|
||||
|
||||
fn List(comptime T: type) type {
|
||||
@@ -2553,6 +2673,53 @@ fn List(comptime T: type) type {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Anonymous Struct Literals#}
|
||||
<p>
|
||||
Zig allows omitting the struct type of a literal. When the result is {#link|coerced|Type Coercion#},
|
||||
the struct literal will directly instantiate the result location, with no copy:
|
||||
</p>
|
||||
{#code_begin|test|struct_result#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const Point = struct {x: i32, y: i32};
|
||||
|
||||
test "anonymous struct literal" {
|
||||
var pt: Point = .{
|
||||
.x = 13,
|
||||
.y = 67,
|
||||
};
|
||||
assert(pt.x == 13);
|
||||
assert(pt.y == 67);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
The struct type can be inferred. Here the result location does not include a type, and
|
||||
so Zig infers the type:
|
||||
</p>
|
||||
{#code_begin|test|struct_anon#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "fully anonymous struct" {
|
||||
dump(.{
|
||||
.int = @as(u32, 1234),
|
||||
.float = @as(f64, 12.34),
|
||||
.b = true,
|
||||
.s = "hi",
|
||||
});
|
||||
}
|
||||
|
||||
fn dump(args: var) void {
|
||||
assert(args.int == 1234);
|
||||
assert(args.float == 12.34);
|
||||
assert(args.b);
|
||||
assert(args.s[0] == 'h');
|
||||
assert(args.s[1] == 'i');
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#see_also|comptime|@fieldParentPtr#}
|
||||
{#header_close#}
|
||||
{#header_open|enum#}
|
||||
@@ -2663,7 +2830,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 'Foo' not allowed in function with calling convention 'ccc'#}
|
||||
{#code_begin|obj_err|parameter of type 'Foo' not allowed in function with calling convention 'C'#}
|
||||
const Foo = enum { A, B, C };
|
||||
export fn entry(foo: Foo) void { }
|
||||
{#code_end#}
|
||||
@@ -2779,6 +2946,7 @@ test "simple union" {
|
||||
This turns the union into a <em>tagged</em> union, which makes it eligible
|
||||
to use with {#link|switch#} expressions. One can use {#link|@TagType#} to
|
||||
obtain the enum type from the union type.
|
||||
Tagged unions coerce to their enum {#link|Type Coercion: unions and enums#}
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
@@ -2795,7 +2963,7 @@ const ComplexType = union(ComplexTypeTag) {
|
||||
|
||||
test "switch on tagged union" {
|
||||
const c = ComplexType{ .Ok = 42 };
|
||||
assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
|
||||
assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
|
||||
|
||||
switch (c) {
|
||||
ComplexTypeTag.Ok => |value| assert(value == 42),
|
||||
@@ -2806,6 +2974,14 @@ test "switch on tagged union" {
|
||||
test "@TagType" {
|
||||
assert(@TagType(ComplexType) == ComplexTypeTag);
|
||||
}
|
||||
|
||||
test "coerce to enum" {
|
||||
const c1 = ComplexType{ .Ok = 42 };
|
||||
const c2 = ComplexType.NotOk;
|
||||
|
||||
assert(c1 == .Ok);
|
||||
assert(c2 == .NotOk);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>In order to modify the payload of a tagged union in a switch expression,
|
||||
place a {#syntax#}*{#endsyntax#} before the variable name to make it a pointer:
|
||||
@@ -2825,7 +3001,7 @@ const ComplexType = union(ComplexTypeTag) {
|
||||
|
||||
test "modify tagged union in switch" {
|
||||
var c = ComplexType{ .Ok = 42 };
|
||||
assert(ComplexTypeTag(c) == ComplexTypeTag.Ok);
|
||||
assert(@as(ComplexTypeTag, c) == ComplexTypeTag.Ok);
|
||||
|
||||
switch (c) {
|
||||
ComplexTypeTag.Ok => |*value| value.* += 1,
|
||||
@@ -2898,6 +3074,32 @@ test "@tagName" {
|
||||
<p>A {#syntax#}packed union{#endsyntax#} has well-defined in-memory layout and is eligible
|
||||
to be in a {#link|packed struct#}.
|
||||
{#header_close#}
|
||||
|
||||
{#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#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
const Number = union {
|
||||
int: i32,
|
||||
float: f64,
|
||||
};
|
||||
|
||||
test "anonymous union literal syntax" {
|
||||
var i: Number = .{.int = 42};
|
||||
var f = makeNumber();
|
||||
assert(i.int == 42);
|
||||
assert(f.float == 12.34);
|
||||
}
|
||||
|
||||
fn makeNumber() Number {
|
||||
return .{.float = 12.34};
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|blocks#}
|
||||
@@ -3393,7 +3595,7 @@ test "for basics" {
|
||||
// This is zero-indexed.
|
||||
var sum2: i32 = 0;
|
||||
for (items) |value, i| {
|
||||
assert(@typeOf(i) == usize);
|
||||
assert(@TypeOf(i) == usize);
|
||||
sum2 += @intCast(i32, i);
|
||||
}
|
||||
assert(sum2 == 10);
|
||||
@@ -3513,6 +3715,14 @@ fn typeNameLength(comptime T: type) usize {
|
||||
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "if expression" {
|
||||
// If expressions are used instead of a ternary expression.
|
||||
const a: u32 = 5;
|
||||
const b: u32 = 4;
|
||||
const result = if (a != b) 47 else 3089;
|
||||
assert(result == 47);
|
||||
}
|
||||
|
||||
test "if boolean" {
|
||||
// If expressions test boolean conditions.
|
||||
const a: u32 = 5;
|
||||
@@ -3524,10 +3734,6 @@ test "if boolean" {
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
|
||||
// If expressions are used instead of a ternary expression.
|
||||
const result = if (a != b) 47 else 3089;
|
||||
assert(result == 47);
|
||||
}
|
||||
|
||||
test "if optional" {
|
||||
@@ -3642,18 +3848,18 @@ test "defer basics" {
|
||||
// If multiple defer statements are specified, they will be executed in
|
||||
// the reverse order they were run.
|
||||
fn deferUnwindExample() void {
|
||||
warn("\n");
|
||||
warn("\n", .{});
|
||||
|
||||
defer {
|
||||
warn("1 ");
|
||||
warn("1 ", .{});
|
||||
}
|
||||
defer {
|
||||
warn("2 ");
|
||||
warn("2 ", .{});
|
||||
}
|
||||
if (false) {
|
||||
// defers are not run if they are never executed.
|
||||
defer {
|
||||
warn("3 ");
|
||||
warn("3 ", .{});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3668,15 +3874,15 @@ test "defer unwinding" {
|
||||
// This is especially useful in allowing a function to clean up properly
|
||||
// on error, and replaces goto error handling tactics as seen in c.
|
||||
fn deferErrorExample(is_error: bool) !void {
|
||||
warn("\nstart of function\n");
|
||||
warn("\nstart of function\n", .{});
|
||||
|
||||
// This will always be executed on exit
|
||||
defer {
|
||||
warn("end of function\n");
|
||||
warn("end of function\n", .{});
|
||||
}
|
||||
|
||||
errdefer {
|
||||
warn("encountered an error!\n");
|
||||
warn("encountered an error!\n", .{});
|
||||
}
|
||||
|
||||
if (is_error) {
|
||||
@@ -3736,7 +3942,7 @@ test "type of unreachable" {
|
||||
// However this assertion will still fail because
|
||||
// evaluating unreachable at compile-time is a compile error.
|
||||
|
||||
assert(@typeOf(unreachable) == noreturn);
|
||||
assert(@TypeOf(unreachable) == noreturn);
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -3769,7 +3975,7 @@ test "noreturn" {
|
||||
<p>Another use case for {#syntax#}noreturn{#endsyntax#} is the {#syntax#}exit{#endsyntax#} function:</p>
|
||||
{#code_begin|test#}
|
||||
{#target_windows#}
|
||||
pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: c_uint) noreturn;
|
||||
pub extern "kernel32" fn ExitProcess(exit_code: c_uint) callconv(.Stdcall) noreturn;
|
||||
|
||||
test "foo" {
|
||||
const value = bar() catch ExitProcess(1);
|
||||
@@ -3803,8 +4009,8 @@ export fn sub(a: i8, b: i8) i8 { return a - b; }
|
||||
// The extern specifier is used to declare a function that will be resolved
|
||||
// at link time, when linking statically, or at runtime, when linking
|
||||
// dynamically.
|
||||
// The stdcallcc specifier changes the calling convention of the function.
|
||||
extern "kernel32" stdcallcc fn ExitProcess(exit_code: u32) noreturn;
|
||||
// The callconv specifier changes the calling convention of the function.
|
||||
extern "kernel32" fn ExitProcess(exit_code: u32) callconv(.Stdcall) noreturn;
|
||||
extern "c" fn atan2(a: f64, b: f64) f64;
|
||||
|
||||
// The @setCold builtin tells the optimizer that a function is rarely called.
|
||||
@@ -3813,9 +4019,9 @@ fn abort() noreturn {
|
||||
while (true) {}
|
||||
}
|
||||
|
||||
// The nakedcc specifier makes a function not have any function prologue or epilogue.
|
||||
// The naked calling convention makes a function not have any function prologue or epilogue.
|
||||
// This can be useful when integrating with assembly.
|
||||
nakedcc fn _start() noreturn {
|
||||
fn _start() callconv(.Naked) noreturn {
|
||||
abort();
|
||||
}
|
||||
|
||||
@@ -3845,7 +4051,7 @@ test "function" {
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
comptime {
|
||||
assert(@typeOf(foo) == fn()void);
|
||||
assert(@TypeOf(foo) == fn()void);
|
||||
assert(@sizeOf(fn()void) == @sizeOf(?fn()void));
|
||||
}
|
||||
|
||||
@@ -3887,14 +4093,37 @@ test "pass struct to function" {
|
||||
<p>
|
||||
For extern functions, Zig follows the C ABI for passing structs and unions by value.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|Function Parameter Type Inference#}
|
||||
<p>
|
||||
Function parameters can be declared with {#syntax#}var{#endsyntax#} in place of the type.
|
||||
In this case the parameter types will be inferred when the function is called.
|
||||
Use {#link|@TypeOf#} and {#link|@typeInfo#} to get information about the inferred type.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
fn addFortyTwo(x: var) @TypeOf(x) {
|
||||
return x + 42;
|
||||
}
|
||||
|
||||
test "fn type inference" {
|
||||
assert(addFortyTwo(1) == 43);
|
||||
assert(@TypeOf(addFortyTwo(1)) == comptime_int);
|
||||
var y: i64 = 2;
|
||||
assert(addFortyTwo(y) == 44);
|
||||
assert(@TypeOf(addFortyTwo(y)) == i64);
|
||||
}
|
||||
{#code_end#}
|
||||
|
||||
{#header_close#}
|
||||
{#header_open|Function Reflection#}
|
||||
{#code_begin|test#}
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "fn reflection" {
|
||||
assert(@typeOf(assert).ReturnType == void);
|
||||
assert(@typeOf(assert).is_var_args == false);
|
||||
assert(@TypeOf(assert).ReturnType == void);
|
||||
assert(@TypeOf(assert).is_var_args == false);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -3912,7 +4141,7 @@ test "fn reflection" {
|
||||
However right now it is hard coded to be a {#syntax#}u16{#endsyntax#}. See <a href="https://github.com/ziglang/zig/issues/786">#768</a>.
|
||||
</p>
|
||||
<p>
|
||||
You can {#link|implicitly cast|Implicit Casts#} an error from a subset to a superset:
|
||||
You can {#link|coerce|Type Coercion#} an error from a subset to a superset:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
@@ -3927,7 +4156,7 @@ const AllocationError = error {
|
||||
OutOfMemory,
|
||||
};
|
||||
|
||||
test "implicit cast subset to superset" {
|
||||
test "coerce subset to superset" {
|
||||
const err = foo(AllocationError.OutOfMemory);
|
||||
std.debug.assert(err == FileOpenError.OutOfMemory);
|
||||
}
|
||||
@@ -3937,7 +4166,7 @@ fn foo(err: AllocationError) FileOpenError {
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
But you cannot implicitly cast an error from a superset to a subset:
|
||||
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#}
|
||||
const FileOpenError = error {
|
||||
@@ -3950,7 +4179,7 @@ const AllocationError = error {
|
||||
OutOfMemory,
|
||||
};
|
||||
|
||||
test "implicit cast superset to subset" {
|
||||
test "coerce superset to subset" {
|
||||
foo(FileOpenError.OutOfMemory) catch {};
|
||||
}
|
||||
|
||||
@@ -3977,7 +4206,7 @@ const err = (error {FileNotFound}).FileNotFound;
|
||||
It is a superset of all other error sets and a subset of none of them.
|
||||
</p>
|
||||
<p>
|
||||
You can implicitly cast any error set to the global one, and you can explicitly
|
||||
You can {#link|coerce|Type Coercion#} any error set to the global one, and you can explicitly
|
||||
cast an error of the global error set to a non-global one. This inserts a language-level
|
||||
assert to make sure the error value is in fact in the destination error set.
|
||||
</p>
|
||||
@@ -4048,7 +4277,7 @@ test "parse u64" {
|
||||
<p>
|
||||
Within the function definition, you can see some return statements that return
|
||||
an error, and at the bottom a return statement that returns a {#syntax#}u64{#endsyntax#}.
|
||||
Both types {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyerror!u64{#endsyntax#}.
|
||||
Both types {#link|coerce|Type Coercion#} to {#syntax#}anyerror!u64{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
What it looks like to use this function varies depending on what you're
|
||||
@@ -4187,17 +4416,17 @@ const assert = @import("std").debug.assert;
|
||||
test "error union" {
|
||||
var foo: anyerror!i32 = undefined;
|
||||
|
||||
// Implicitly cast from child type of an error union:
|
||||
// Coerce from child type of an error union:
|
||||
foo = 1234;
|
||||
|
||||
// Implicitly cast from an error set:
|
||||
// Coerce from an error set:
|
||||
foo = error.SomeError;
|
||||
|
||||
// Use compile-time reflection to access the payload type of an error union:
|
||||
comptime assert(@typeOf(foo).Payload == i32);
|
||||
comptime assert(@TypeOf(foo).Payload == i32);
|
||||
|
||||
// Use compile-time reflection to access the error set type of an error union:
|
||||
comptime assert(@typeOf(foo).ErrorSet == anyerror);
|
||||
comptime assert(@TypeOf(foo).ErrorSet == anyerror);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_open|Merging Error Sets#}
|
||||
@@ -4567,14 +4796,14 @@ fn doAThing(optional_foo: ?*Foo) void {
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "optional type" {
|
||||
// Declare an optional and implicitly cast from null:
|
||||
// Declare an optional and coerce from null:
|
||||
var foo: ?i32 = null;
|
||||
|
||||
// Implicitly cast from child type of an optional
|
||||
// Coerce from child type of an optional
|
||||
foo = 1234;
|
||||
|
||||
// Use compile-time reflection to access the child type of the optional:
|
||||
comptime assert(@typeOf(foo).Child == i32);
|
||||
comptime assert(@TypeOf(foo).Child == i32);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -4613,38 +4842,38 @@ test "optional pointers" {
|
||||
{#header_open|Casting#}
|
||||
<p>
|
||||
A <strong>type cast</strong> converts a value of one type to another.
|
||||
Zig has {#link|Implicit Casts#} for conversions that are known to be completely safe and unambiguous,
|
||||
Zig has {#link|Type Coercion#} for conversions that are known to be completely safe and unambiguous,
|
||||
and {#link|Explicit Casts#} for conversions that one would not want to happen on accident.
|
||||
There is also a third kind of type conversion called {#link|Peer Type Resolution#} for
|
||||
the case when a result type must be decided given multiple operand types.
|
||||
</p>
|
||||
{#header_open|Implicit Casts#}
|
||||
{#header_open|Type Coercion#}
|
||||
<p>
|
||||
An implicit cast occurs when one type is expected, but different type is provided:
|
||||
Type coercion occurs when one type is expected, but different type is provided:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
test "implicit cast - variable declaration" {
|
||||
test "type coercion - variable declaration" {
|
||||
var a: u8 = 1;
|
||||
var b: u16 = a;
|
||||
}
|
||||
|
||||
test "implicit cast - function call" {
|
||||
test "type coercion - function call" {
|
||||
var a: u8 = 1;
|
||||
foo(a);
|
||||
}
|
||||
|
||||
fn foo(b: u16) void {}
|
||||
|
||||
test "implicit cast - invoke a type as a function" {
|
||||
test "type coercion - @as builtin" {
|
||||
var a: u8 = 1;
|
||||
var b = u16(a);
|
||||
var b = @as(u16, a);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
Implicit casts are only allowed when it is completely unambiguous how to get from one type to another,
|
||||
Type coercions are only allowed when it is completely unambiguous how to get from one type to another,
|
||||
and the transformation is guaranteed to be safe. There is one exception, which is {#link|C Pointers#}.
|
||||
</p>
|
||||
{#header_open|Implicit Cast: Stricter Qualification#}
|
||||
{#header_open|Type Coercion: Stricter Qualification#}
|
||||
<p>
|
||||
Values which have the same representation at runtime can be cast to increase the strictness
|
||||
of the qualifiers, no matter how nested the qualifiers are:
|
||||
@@ -4659,7 +4888,7 @@ test "implicit cast - invoke a type as a function" {
|
||||
These casts are no-ops at runtime since the value representation does not change.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
test "implicit cast - const qualification" {
|
||||
test "type coercion - const qualification" {
|
||||
var a: i32 = 1;
|
||||
var b: *i32 = &a;
|
||||
foo(b);
|
||||
@@ -4668,7 +4897,7 @@ test "implicit cast - const qualification" {
|
||||
fn foo(a: *const i32) void {}
|
||||
{#code_end#}
|
||||
<p>
|
||||
In addition, pointers implicitly cast to const optional pointers:
|
||||
In addition, pointers coerce to const optional pointers:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
@@ -4676,16 +4905,16 @@ const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
|
||||
test "cast *[1][*]const u8 to [*]const ?[*]const u8" {
|
||||
const window_name = [1][*]const u8{c"window name"};
|
||||
const window_name = [1][*]const u8{"window name"};
|
||||
const x: [*]const ?[*]const u8 = &window_name;
|
||||
assert(mem.eql(u8, std.mem.toSliceConst(u8, x[0].?), "window name"));
|
||||
assert(mem.eql(u8, std.mem.toSliceConst(u8, @ptrCast([*:0]const u8, x[0].?)), "window name"));
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Integer and Float Widening#}
|
||||
{#header_open|Type Coercion: Integer and Float Widening#}
|
||||
<p>
|
||||
{#link|Integers#} implicitly cast to integer types which can represent every value of the old type, and likewise
|
||||
{#link|Floats#} implicitly cast to float types which can represent every value of the old type.
|
||||
{#link|Integers#} coerce to integer types which can represent every value of the old type, and likewise
|
||||
{#link|Floats#} coerce to float types which can represent every value of the old type.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
@@ -4717,8 +4946,8 @@ test "float widening" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Arrays and Pointers#}
|
||||
{#code_begin|test#}
|
||||
{#header_open|Type Coercion: Arrays and Pointers#}
|
||||
{#code_begin|test|coerce_arrays_and_ptrs#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
@@ -4728,48 +4957,48 @@ const assert = std.debug.assert;
|
||||
// https://github.com/ziglang/zig/issues/265 is implemented.
|
||||
test "[N]T to []const T" {
|
||||
var x1: []const u8 = "hello";
|
||||
var x2: []const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
var x2: []const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
assert(std.mem.eql(u8, x1, x2));
|
||||
|
||||
var y: []const f32 = [2]f32{ 1.2, 3.4 };
|
||||
var y: []const f32 = &[2]f32{ 1.2, 3.4 };
|
||||
assert(y[0] == 1.2);
|
||||
}
|
||||
|
||||
// Likewise, it works when the destination type is an error union.
|
||||
test "[N]T to E![]const T" {
|
||||
var x1: anyerror![]const u8 = "hello";
|
||||
var x2: anyerror![]const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
var x2: anyerror![]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
assert(std.mem.eql(u8, try x1, try x2));
|
||||
|
||||
var y: anyerror![]const f32 = [2]f32{ 1.2, 3.4 };
|
||||
var y: anyerror![]const f32 = &[2]f32{ 1.2, 3.4 };
|
||||
assert((try y)[0] == 1.2);
|
||||
}
|
||||
|
||||
// Likewise, it works when the destination type is an optional.
|
||||
test "[N]T to ?[]const T" {
|
||||
var x1: ?[]const u8 = "hello";
|
||||
var x2: ?[]const u8 = [5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
var x2: ?[]const u8 = &[5]u8{ 'h', 'e', 'l', 'l', 111 };
|
||||
assert(std.mem.eql(u8, x1.?, x2.?));
|
||||
|
||||
var y: ?[]const f32 = [2]f32{ 1.2, 3.4 };
|
||||
var y: ?[]const f32 = &[2]f32{ 1.2, 3.4 };
|
||||
assert(y.?[0] == 1.2);
|
||||
}
|
||||
|
||||
// In this cast, the array length becomes the slice length.
|
||||
test "*[N]T to []T" {
|
||||
var buf: [5]u8 = "hello";
|
||||
var buf: [5]u8 = "hello".*;
|
||||
const x: []u8 = &buf;
|
||||
assert(std.mem.eql(u8, x, "hello"));
|
||||
|
||||
const buf2 = [2]f32{ 1.2, 3.4 };
|
||||
const x2: []const f32 = &buf2;
|
||||
assert(std.mem.eql(f32, x2, [2]f32{ 1.2, 3.4 }));
|
||||
assert(std.mem.eql(f32, x2, &[2]f32{ 1.2, 3.4 }));
|
||||
}
|
||||
|
||||
// Single-item pointers to arrays can be implicitly casted to
|
||||
// Single-item pointers to arrays can be coerced to
|
||||
// unknown length pointers.
|
||||
test "*[N]T to [*]T" {
|
||||
var buf: [5]u8 = "hello";
|
||||
var buf: [5]u8 = "hello".*;
|
||||
const x: [*]u8 = &buf;
|
||||
assert(x[4] == 'o');
|
||||
// x[5] would be an uncaught out of bounds pointer dereference!
|
||||
@@ -4777,7 +5006,7 @@ test "*[N]T to [*]T" {
|
||||
|
||||
// Likewise, it works when the destination type is an optional.
|
||||
test "*[N]T to ?[*]T" {
|
||||
var buf: [5]u8 = "hello";
|
||||
var buf: [5]u8 = "hello".*;
|
||||
const x: ?[*]u8 = &buf;
|
||||
assert(x.?[4] == 'o');
|
||||
}
|
||||
@@ -4792,15 +5021,15 @@ test "*T to *[1]T" {
|
||||
{#code_end#}
|
||||
{#see_also|C Pointers#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Optionals#}
|
||||
{#header_open|Type Coercion: Optionals#}
|
||||
<p>
|
||||
The payload type of {#link|Optionals#}, as well as {#link|null#}, implicitly cast to the optional type.
|
||||
The payload type of {#link|Optionals#}, as well as {#link|null#}, coerce to the optional type.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "implicit casting to optionals" {
|
||||
test "coerce to optionals" {
|
||||
const x: ?i32 = 1234;
|
||||
const y: ?i32 = null;
|
||||
|
||||
@@ -4813,7 +5042,7 @@ test "implicit casting to optionals" {
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "implicit casting to optionals wrapped in error union" {
|
||||
test "coerce to optionals wrapped in error union" {
|
||||
const x: anyerror!?i32 = 1234;
|
||||
const y: anyerror!?i32 = null;
|
||||
|
||||
@@ -4822,15 +5051,15 @@ test "implicit casting to optionals wrapped in error union" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Error Unions#}
|
||||
{#header_open|Type Coercion: Error Unions#}
|
||||
<p>The payload type of an {#link|Error Union Type#} as well as the {#link|Error Set Type#}
|
||||
implicitly cast to the error union type:
|
||||
coerce to the error union type:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "implicit casting to error unions" {
|
||||
test "coercion to error unions" {
|
||||
const x: anyerror!i32 = 1234;
|
||||
const y: anyerror!i32 = error.Failure;
|
||||
|
||||
@@ -4839,23 +5068,23 @@ test "implicit casting to error unions" {
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Compile-Time Known Numbers#}
|
||||
{#header_open|Type Coercion: Compile-Time Known Numbers#}
|
||||
<p>When a number is {#link|comptime#}-known to be representable in the destination type,
|
||||
it may be implicitly casted:
|
||||
it may be coerced:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "implicit casting large integer type to smaller one when value is comptime known to fit" {
|
||||
test "coercing large integer type to smaller one when value is comptime known to fit" {
|
||||
const x: u64 = 255;
|
||||
const y: u8 = x;
|
||||
assert(y == 255);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: unions and enums#}
|
||||
<p>Tagged unions can be implicitly cast to enums, and enums can be implicitly casted to tagged unions
|
||||
{#header_open|Type Coercion: unions and enums#}
|
||||
<p>Tagged unions can be coerced to enums, and enums can be coerced to tagged unions
|
||||
when they are {#link|comptime#}-known to be a field of the union that has only one possible value, such as
|
||||
{#link|void#}:
|
||||
</p>
|
||||
@@ -4875,7 +5104,7 @@ const U = union(E) {
|
||||
Three,
|
||||
};
|
||||
|
||||
test "implicit casting between unions and enums" {
|
||||
test "coercion between unions and enums" {
|
||||
var u = U{ .Two = 12.34 };
|
||||
var e: E = u;
|
||||
assert(e == E.Two);
|
||||
@@ -4887,20 +5116,20 @@ test "implicit casting between unions and enums" {
|
||||
{#code_end#}
|
||||
{#see_also|union|enum#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: Zero Bit Types#}
|
||||
<p>{#link|Zero Bit Types#} may be implicitly casted to single-item {#link|Pointers#},
|
||||
{#header_open|Type Coercion: Zero Bit Types#}
|
||||
<p>{#link|Zero Bit Types#} may be coerced to single-item {#link|Pointers#},
|
||||
regardless of const.</p>
|
||||
<p>TODO document the reasoning for this</p>
|
||||
<p>TODO document whether vice versa should work and why</p>
|
||||
{#code_begin|test#}
|
||||
test "implicit casting of zero bit types" {
|
||||
test "coercion of zero bit types" {
|
||||
var x: void = {};
|
||||
var y: *void = x;
|
||||
//var z: void = y; // TODO
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_open|Implicit Cast: undefined#}
|
||||
{#header_open|Type Coercion: undefined#}
|
||||
<p>{#link|undefined#} can be cast to any type.</p>
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
@@ -4945,10 +5174,10 @@ test "implicit casting of zero bit types" {
|
||||
<li>Some {#link|binary operations|Table of Operators#}</li>
|
||||
</ul>
|
||||
<p>
|
||||
This kind of type resolution chooses a type that all peer types can implicitly cast into. Here are
|
||||
This kind of type resolution chooses a type that all peer types can coerce into. Here are
|
||||
some examples:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
{#code_begin|test|peer_type_resolution#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
const mem = std.mem;
|
||||
@@ -4958,7 +5187,7 @@ test "peer resolve int widening" {
|
||||
var b: i16 = 34;
|
||||
var c = a + b;
|
||||
assert(c == 46);
|
||||
assert(@typeOf(c) == i16);
|
||||
assert(@TypeOf(c) == i16);
|
||||
}
|
||||
|
||||
test "peer resolve arrays of different size to const slice" {
|
||||
@@ -4976,8 +5205,8 @@ test "peer resolve array and const slice" {
|
||||
comptime testPeerResolveArrayConstSlice(true);
|
||||
}
|
||||
fn testPeerResolveArrayConstSlice(b: bool) void {
|
||||
const value1 = if (b) "aoeu" else ([]const u8)("zz");
|
||||
const value2 = if (b) ([]const u8)("zz") else "aoeu";
|
||||
const value1 = if (b) "aoeu" else @as([]const u8, "zz");
|
||||
const value2 = if (b) @as([]const u8, "zz") else "aoeu";
|
||||
assert(mem.eql(u8, value1, "aoeu"));
|
||||
assert(mem.eql(u8, value2, "zz"));
|
||||
}
|
||||
@@ -4992,13 +5221,13 @@ test "peer type resolution: ?T and T" {
|
||||
}
|
||||
fn peerTypeTAndOptionalT(c: bool, b: bool) ?usize {
|
||||
if (c) {
|
||||
return if (b) null else usize(0);
|
||||
return if (b) null else @as(usize, 0);
|
||||
}
|
||||
|
||||
return usize(3);
|
||||
return @as(usize, 3);
|
||||
}
|
||||
|
||||
test "peer type resolution: [0]u8 and []const u8" {
|
||||
test "peer type resolution: *[0]u8 and []const u8" {
|
||||
assert(peerTypeEmptyArrayAndSlice(true, "hi").len == 0);
|
||||
assert(peerTypeEmptyArrayAndSlice(false, "hi").len == 1);
|
||||
comptime {
|
||||
@@ -5008,20 +5237,20 @@ test "peer type resolution: [0]u8 and []const u8" {
|
||||
}
|
||||
fn peerTypeEmptyArrayAndSlice(a: bool, slice: []const u8) []const u8 {
|
||||
if (a) {
|
||||
return [_]u8{};
|
||||
return &[_]u8{};
|
||||
}
|
||||
|
||||
return slice[0..1];
|
||||
}
|
||||
test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
|
||||
test "peer type resolution: *[0]u8, []const u8, and anyerror![]u8" {
|
||||
{
|
||||
var data = "hi";
|
||||
var data = "hi".*;
|
||||
const slice = data[0..];
|
||||
assert((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
|
||||
assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
|
||||
}
|
||||
comptime {
|
||||
var data = "hi";
|
||||
var data = "hi".*;
|
||||
const slice = data[0..];
|
||||
assert((try peerTypeEmptyArrayAndSliceAndError(true, slice)).len == 0);
|
||||
assert((try peerTypeEmptyArrayAndSliceAndError(false, slice)).len == 1);
|
||||
@@ -5029,15 +5258,15 @@ test "peer type resolution: [0]u8, []const u8, and anyerror![]u8" {
|
||||
}
|
||||
fn peerTypeEmptyArrayAndSliceAndError(a: bool, slice: []u8) anyerror![]u8 {
|
||||
if (a) {
|
||||
return [_]u8{};
|
||||
return &[_]u8{};
|
||||
}
|
||||
|
||||
return slice[0..1];
|
||||
}
|
||||
|
||||
test "peer type resolution: *const T and ?*T" {
|
||||
const a = @intToPtr(*const usize, 0x123456789);
|
||||
const b = @intToPtr(?*usize, 0x123456789);
|
||||
const a = @intToPtr(*const usize, 0x123456780);
|
||||
const b = @intToPtr(?*usize, 0x123456780);
|
||||
assert(a == b);
|
||||
assert(b == a);
|
||||
}
|
||||
@@ -5258,11 +5487,9 @@ fn gimmeTheBiggerInteger(a: u64, b: u64) u64 {
|
||||
<li>In the function definition, the value is known at compile-time.</li>
|
||||
</ul>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
For example, if we were to introduce another function to the above snippet:
|
||||
</p>
|
||||
{#code_begin|test_err|cannot store runtime value in type 'type'#}
|
||||
{#code_begin|test_err|values of type 'type' must be comptime known#}
|
||||
fn max(comptime T: type, a: T, b: T) T {
|
||||
return if (a > b) a else b;
|
||||
}
|
||||
@@ -5559,7 +5786,7 @@ test "fibonacci" {
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const first_25_primes = firstNPrimes(25);
|
||||
const sum_of_first_25_primes = sum(first_25_primes);
|
||||
const sum_of_first_25_primes = sum(&first_25_primes);
|
||||
|
||||
fn firstNPrimes(comptime n: usize) [n]i32 {
|
||||
var prime_list: [n]i32 = undefined;
|
||||
@@ -5658,7 +5885,7 @@ const a_number: i32 = 1234;
|
||||
const a_string = "foobar";
|
||||
|
||||
pub fn main() void {
|
||||
warn("here is a string: '{}' here is a number: {}\n", a_string, a_number);
|
||||
warn("here is a string: '{}' here is a number: {}\n", .{a_string, a_number});
|
||||
}
|
||||
{#code_end#}
|
||||
|
||||
@@ -5668,7 +5895,7 @@ pub fn main() void {
|
||||
|
||||
{#code_begin|syntax#}
|
||||
/// Calls print and then flushes the buffer.
|
||||
pub fn printf(self: *OutStream, comptime format: []const u8, args: ...) anyerror!void {
|
||||
pub fn printf(self: *OutStream, comptime format: []const u8, args: var) anyerror!void {
|
||||
const State = enum {
|
||||
Start,
|
||||
OpenBrace,
|
||||
@@ -5755,7 +5982,7 @@ pub fn printf(self: *OutStream, arg0: i32, arg1: []const u8) !void {
|
||||
</p>
|
||||
{#code_begin|syntax#}
|
||||
pub fn printValue(self: *OutStream, value: var) !void {
|
||||
const T = @typeOf(value);
|
||||
const T = @TypeOf(value);
|
||||
if (@isInteger(T)) {
|
||||
return self.printInt(T, value);
|
||||
} else if (@isFloat(T)) {
|
||||
@@ -5775,8 +6002,11 @@ const a_number: i32 = 1234;
|
||||
const a_string = "foobar";
|
||||
|
||||
test "printf too many arguments" {
|
||||
warn("here is a string: '{}' here is a number: {}\n",
|
||||
a_string, a_number, a_number);
|
||||
warn("here is a string: '{}' here is a number: {}\n", .{
|
||||
a_string,
|
||||
a_number,
|
||||
a_number,
|
||||
});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -5784,7 +6014,7 @@ test "printf too many arguments" {
|
||||
</p>
|
||||
<p>
|
||||
Zig doesn't care whether the format argument is a string literal,
|
||||
only that it is a compile-time known value that is implicitly castable to a {#syntax#}[]const u8{#endsyntax#}:
|
||||
only that it is a compile-time known value that can be coerced to a {#syntax#}[]const u8{#endsyntax#}:
|
||||
</p>
|
||||
{#code_begin|exe|printf#}
|
||||
const warn = @import("std").debug.warn;
|
||||
@@ -5794,7 +6024,7 @@ const a_string = "foobar";
|
||||
const fmt = "here is a string: '{}' here is a number: {}\n";
|
||||
|
||||
pub fn main() void {
|
||||
warn(fmt, a_string, a_number);
|
||||
warn(fmt, .{a_string, a_number});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -5819,7 +6049,7 @@ pub fn main() void {
|
||||
{#target_linux_x86_64#}
|
||||
pub fn main() noreturn {
|
||||
const msg = "hello world\n";
|
||||
_ = syscall3(SYS_write, STDOUT_FILENO, @ptrToInt(&msg), msg.len);
|
||||
_ = syscall3(SYS_write, STDOUT_FILENO, @ptrToInt(msg), msg.len);
|
||||
_ = syscall1(SYS_exit, 0);
|
||||
unreachable;
|
||||
}
|
||||
@@ -6068,7 +6298,7 @@ test "async function suspend with block" {
|
||||
|
||||
fn testSuspendBlock() void {
|
||||
suspend {
|
||||
comptime assert(@typeOf(@frame()) == *@Frame(testSuspendBlock));
|
||||
comptime assert(@TypeOf(@frame()) == *@Frame(testSuspendBlock));
|
||||
the_frame = @frame();
|
||||
}
|
||||
result = true;
|
||||
@@ -6135,7 +6365,7 @@ test "async and await" {
|
||||
|
||||
fn amain() void {
|
||||
var frame = async func();
|
||||
comptime assert(@typeOf(frame) == @Frame(func));
|
||||
comptime assert(@TypeOf(frame) == @Frame(func));
|
||||
|
||||
const ptr: anyframe->void = &frame;
|
||||
const any_ptr: anyframe = ptr;
|
||||
@@ -6154,7 +6384,7 @@ fn func() void {
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}await{#endsyntax#} is a suspend point, and takes as an operand anything that
|
||||
implicitly casts to {#syntax#}anyframe->T{#endsyntax#}.
|
||||
coerces to {#syntax#}anyframe->T{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
There is a common misconception that {#syntax#}await{#endsyntax#} resumes the target function.
|
||||
@@ -6177,7 +6407,7 @@ test "async function await" {
|
||||
resume the_frame;
|
||||
seq('i');
|
||||
assert(final_result == 1234);
|
||||
assert(std.mem.eql(u8, seq_points, "abcdefghi"));
|
||||
assert(std.mem.eql(u8, &seq_points, "abcdefghi"));
|
||||
}
|
||||
fn amain() void {
|
||||
seq('b');
|
||||
@@ -6232,7 +6462,7 @@ pub fn main() void {
|
||||
|
||||
fn amainWrap() void {
|
||||
amain() catch |e| {
|
||||
std.debug.warn("{}\n", e);
|
||||
std.debug.warn("{}\n", .{e});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
@@ -6241,7 +6471,7 @@ fn amainWrap() void {
|
||||
}
|
||||
|
||||
fn amain() !void {
|
||||
const allocator = std.heap.direct_allocator;
|
||||
const allocator = std.heap.page_allocator;
|
||||
var download_frame = async fetchUrl(allocator, "https://example.com/");
|
||||
var awaited_download_frame = false;
|
||||
errdefer if (!awaited_download_frame) {
|
||||
@@ -6262,8 +6492,8 @@ fn amain() !void {
|
||||
const download_text = try await download_frame;
|
||||
defer allocator.free(download_text);
|
||||
|
||||
std.debug.warn("download_text: {}\n", download_text);
|
||||
std.debug.warn("file_text: {}\n", file_text);
|
||||
std.debug.warn("download_text: {}\n", .{download_text});
|
||||
std.debug.warn("file_text: {}\n", .{file_text});
|
||||
}
|
||||
|
||||
var global_download_frame: anyframe = undefined;
|
||||
@@ -6273,7 +6503,7 @@ fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
|
||||
suspend {
|
||||
global_download_frame = @frame();
|
||||
}
|
||||
std.debug.warn("fetchUrl returning\n");
|
||||
std.debug.warn("fetchUrl returning\n", .{});
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -6284,7 +6514,7 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
|
||||
suspend {
|
||||
global_file_frame = @frame();
|
||||
}
|
||||
std.debug.warn("readFile returning\n");
|
||||
std.debug.warn("readFile returning\n", .{});
|
||||
return result;
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -6302,7 +6532,7 @@ pub fn main() void {
|
||||
|
||||
fn amainWrap() void {
|
||||
amain() catch |e| {
|
||||
std.debug.warn("{}\n", e);
|
||||
std.debug.warn("{}\n", .{e});
|
||||
if (@errorReturnTrace()) |trace| {
|
||||
std.debug.dumpStackTrace(trace.*);
|
||||
}
|
||||
@@ -6311,7 +6541,7 @@ fn amainWrap() void {
|
||||
}
|
||||
|
||||
fn amain() !void {
|
||||
const allocator = std.heap.direct_allocator;
|
||||
const allocator = std.heap.page_allocator;
|
||||
var download_frame = async fetchUrl(allocator, "https://example.com/");
|
||||
var awaited_download_frame = false;
|
||||
errdefer if (!awaited_download_frame) {
|
||||
@@ -6332,21 +6562,21 @@ fn amain() !void {
|
||||
const download_text = try await download_frame;
|
||||
defer allocator.free(download_text);
|
||||
|
||||
std.debug.warn("download_text: {}\n", download_text);
|
||||
std.debug.warn("file_text: {}\n", file_text);
|
||||
std.debug.warn("download_text: {}\n", .{download_text});
|
||||
std.debug.warn("file_text: {}\n", .{file_text});
|
||||
}
|
||||
|
||||
fn fetchUrl(allocator: *Allocator, url: []const u8) ![]u8 {
|
||||
const result = try std.mem.dupe(allocator, u8, "this is the downloaded url contents");
|
||||
errdefer allocator.free(result);
|
||||
std.debug.warn("fetchUrl returning\n");
|
||||
std.debug.warn("fetchUrl returning\n", .{});
|
||||
return result;
|
||||
}
|
||||
|
||||
fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
|
||||
const result = try std.mem.dupe(allocator, u8, "this is the file contents");
|
||||
errdefer allocator.free(result);
|
||||
std.debug.warn("readFile returning\n");
|
||||
std.debug.warn("readFile returning\n", .{});
|
||||
return result;
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -6359,7 +6589,7 @@ fn readFile(allocator: *Allocator, filename: []const u8) ![]u8 {
|
||||
{#header_close#}
|
||||
|
||||
{#header_close#}
|
||||
{#header_open|Builtin Functions|3col#}
|
||||
{#header_open|Builtin Functions|2col#}
|
||||
<p>
|
||||
Builtin functions are provided by the compiler and are prefixed with <code>@</code>.
|
||||
The {#syntax#}comptime{#endsyntax#} keyword on a parameter means that the parameter must be known
|
||||
@@ -6414,6 +6644,14 @@ comptime {
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@as#}
|
||||
<pre>{#syntax#}@as(comptime T: type, expression) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
Performs {#link|Type Coercion#}. This cast is allowed when the conversion is unambiguous and safe,
|
||||
and is the preferred way to convert between types, whenever possible.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@asyncCall#}
|
||||
<pre>{#syntax#}@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: ...) anyframe->T{#endsyntax#}</pre>
|
||||
<p>
|
||||
@@ -6462,14 +6700,14 @@ async fn func(y: *i32) void {
|
||||
This builtin function atomically dereferences a pointer and returns the value.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#},
|
||||
or an integer whose bit count meets these requirements:
|
||||
{#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer whose bit count meets these requirements:
|
||||
</p>
|
||||
<ul>
|
||||
<li>At least 8</li>
|
||||
<li>At most the same as usize</li>
|
||||
<li>Power of 2</li>
|
||||
</ul>
|
||||
</ul> or an enum with a valid integer tag type.
|
||||
<p>
|
||||
TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
|
||||
we can remove this restriction
|
||||
@@ -6497,7 +6735,7 @@ async fn func(y: *i32) void {
|
||||
Supported operations:
|
||||
</p>
|
||||
<ul>
|
||||
<li>{#syntax#}.Xchg{#endsyntax#} - stores the operand unmodified.</li>
|
||||
<li>{#syntax#}.Xchg{#endsyntax#} - stores the operand unmodified. Supports enums, integers and floats.</li>
|
||||
<li>{#syntax#}.Add{#endsyntax#} - for integers, twos complement wraparound addition.
|
||||
Also supports {#link|Floats#}.</li>
|
||||
<li>{#syntax#}.Sub{#endsyntax#} - for integers, twos complement wraparound subtraction.
|
||||
@@ -6510,13 +6748,32 @@ async fn func(y: *i32) void {
|
||||
<li>{#syntax#}.Min{#endsyntax#} - stores the operand if it is smaller. Supports integers and floats.</li>
|
||||
</ul>
|
||||
{#header_close#}
|
||||
{#header_open|@atomicStore#}
|
||||
<pre>{#syntax#}@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
This builtin function atomically stores a value.
|
||||
</p>
|
||||
<p>
|
||||
{#syntax#}T{#endsyntax#} must be a pointer type, a {#syntax#}bool{#endsyntax#}, a float,
|
||||
an integer whose bit count meets these requirements:
|
||||
</p>
|
||||
<ul>
|
||||
<li>At least 8</li>
|
||||
<li>At most the same as usize</li>
|
||||
<li>Power of 2</li>
|
||||
</ul> or an enum with a valid integer tag type.
|
||||
<p>
|
||||
TODO right now bool is not accepted. Also I think we could make non powers of 2 work fine, maybe
|
||||
we can remove this restriction
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@bitCast#}
|
||||
<pre>{#syntax#}@bitCast(comptime DestType: type, value: var) DestType{#endsyntax#}</pre>
|
||||
<p>
|
||||
Converts a value of one type to another type.
|
||||
</p>
|
||||
<p>
|
||||
Asserts that {#syntax#}@sizeOf(@typeOf(value)) == @sizeOf(DestType){#endsyntax#}.
|
||||
Asserts that {#syntax#}@sizeOf(@TypeOf(value)) == @sizeOf(DestType){#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
Asserts that {#syntax#}@typeId(DestType) != @import("builtin").TypeId.Pointer{#endsyntax#}. Use {#syntax#}@ptrCast{#endsyntax#} or {#syntax#}@intToPtr{#endsyntax#} if you need this.
|
||||
@@ -6572,9 +6829,12 @@ async fn func(y: *i32) void {
|
||||
{#header_open|@mulAdd#}
|
||||
<pre>{#syntax#}@mulAdd(comptime T: type, a: T, b: T, c: T) T{#endsyntax#}</pre>
|
||||
<p>
|
||||
Fused multiply add (for floats), similar to {#syntax#}(a * b) + c{#endsyntax#}, except
|
||||
Fused multiply add, similar to {#syntax#}(a * b) + c{#endsyntax#}, except
|
||||
only rounds once, and is thus more accurate.
|
||||
</p>
|
||||
<p>
|
||||
Supports Floats and Vectors of floats.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@byteSwap#}
|
||||
@@ -6627,6 +6887,102 @@ async fn func(y: *i32) void {
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@call#}
|
||||
<pre>{#syntax#}@call(options: std.builtin.CallOptions, function: var, args: var) var{#endsyntax#}</pre>
|
||||
<p>
|
||||
Calls a function, in the same way that invoking an expression with parentheses does:
|
||||
</p>
|
||||
{#code_begin|test|call#}
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "noinline function call" {
|
||||
assert(@call(.{}, add, .{3, 9}) == 12);
|
||||
}
|
||||
|
||||
fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
{#syntax#}@call{#endsyntax#} allows more flexibility than normal function call syntax does. The
|
||||
{#syntax#}CallOptions{#endsyntax#} struct is reproduced here:
|
||||
</p>
|
||||
{#code_begin|syntax#}
|
||||
pub const CallOptions = struct {
|
||||
modifier: Modifier = .auto,
|
||||
stack: ?[]align(std.Target.stack_align) u8 = null,
|
||||
|
||||
pub const Modifier = enum {
|
||||
/// Equivalent to function call syntax.
|
||||
auto,
|
||||
|
||||
/// Equivalent to async keyword used with function call syntax.
|
||||
async_kw,
|
||||
|
||||
/// Prevents tail call optimization. This guarantees that the return
|
||||
/// address will point to the callsite, as opposed to the callsite's
|
||||
/// callsite. If the call is otherwise required to be tail-called
|
||||
/// or inlined, a compile error is emitted instead.
|
||||
never_tail,
|
||||
|
||||
/// Guarantees that the call will not be inlined. If the call is
|
||||
/// otherwise required to be inlined, a compile error is emitted instead.
|
||||
never_inline,
|
||||
|
||||
/// Asserts that the function call will not suspend. This allows a
|
||||
/// non-async function to call an async function.
|
||||
no_async,
|
||||
|
||||
/// Guarantees that the call will be generated with tail call optimization.
|
||||
/// If this is not possible, a compile error is emitted instead.
|
||||
always_tail,
|
||||
|
||||
/// Guarantees that the call will inlined at the callsite.
|
||||
/// If this is not possible, a compile error is emitted instead.
|
||||
always_inline,
|
||||
|
||||
/// Evaluates the call at compile-time. If the call cannot be completed at
|
||||
/// compile-time, a compile error is emitted instead.
|
||||
compile_time,
|
||||
};
|
||||
};
|
||||
{#code_end#}
|
||||
|
||||
{#header_open|Calling with a New Stack#}
|
||||
<p>
|
||||
When the {#syntax#}stack{#endsyntax#} option is provided, instead of using the same stack as the caller, the function uses the provided stack.
|
||||
</p>
|
||||
{#code_begin|test|new_stack_call#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
var new_stack_bytes: [1024]u8 align(16) = undefined;
|
||||
|
||||
test "calling a function with a new stack" {
|
||||
const arg = 1234;
|
||||
|
||||
const a = @call(.{.stack = new_stack_bytes[0..512]}, targetFunction, .{arg});
|
||||
const b = @call(.{.stack = new_stack_bytes[512..]}, targetFunction, .{arg});
|
||||
_ = targetFunction(arg);
|
||||
|
||||
assert(arg == 1234);
|
||||
assert(a < b);
|
||||
}
|
||||
|
||||
fn targetFunction(x: i32) usize {
|
||||
assert(x == 1234);
|
||||
|
||||
var local_variable: i32 = 42;
|
||||
const ptr = &local_variable;
|
||||
ptr.* += 1;
|
||||
|
||||
assert(local_variable == 43);
|
||||
return @ptrToInt(ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@cDefine#}
|
||||
<pre>{#syntax#}@cDefine(comptime name: []u8, value){#endsyntax#}</pre>
|
||||
<p>
|
||||
@@ -6677,7 +7033,7 @@ async fn func(y: *i32) void {
|
||||
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
|
||||
</p>
|
||||
<p>
|
||||
This appends <code>#include <$path>\n</code> to the {#syntax#}c_import{#endsyntax#}
|
||||
This appends <code>#include <$path>\n</code> to the {#syntax#}c_import{#endsyntax#}
|
||||
temporary buffer.
|
||||
</p>
|
||||
{#see_also|Import from C Header File|@cImport|@cDefine|@cUndef#}
|
||||
@@ -6725,7 +7081,7 @@ fn cmpxchgStrongButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_v
|
||||
<p>
|
||||
{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}.
|
||||
</p>
|
||||
<p>{#syntax#}@typeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
<p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
{#see_also|Compile Variables|cmpxchgWeak#}
|
||||
{#header_close#}
|
||||
{#header_open|@cmpxchgWeak#}
|
||||
@@ -6753,7 +7109,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
<p>
|
||||
{#syntax#}AtomicOrder{#endsyntax#} can be found with {#syntax#}@import("builtin").AtomicOrder{#endsyntax#}.
|
||||
</p>
|
||||
<p>{#syntax#}@typeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
<p>{#syntax#}@TypeOf(ptr).alignment{#endsyntax#} must be {#syntax#}>= @sizeOf(T).{#endsyntax#}</p>
|
||||
{#see_also|Compile Variables|cmpxchgStrong#}
|
||||
{#header_close#}
|
||||
|
||||
@@ -6798,10 +7154,9 @@ const num1 = blk: {
|
||||
test "main" {
|
||||
@compileLog("comptime in main");
|
||||
|
||||
warn("Runtime in main, num1 = {}.\n", num1);
|
||||
warn("Runtime in main, num1 = {}.\n", .{num1});
|
||||
}
|
||||
{#code_end#}
|
||||
</p>
|
||||
<p>
|
||||
will ouput:
|
||||
</p>
|
||||
@@ -6820,7 +7175,7 @@ const num1 = blk: {
|
||||
};
|
||||
|
||||
test "main" {
|
||||
warn("Runtime in main, num1 = {}.\n", num1);
|
||||
warn("Runtime in main, num1 = {}.\n", .{num1});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -6973,21 +7328,21 @@ test "main" {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@export#}
|
||||
<pre>{#syntax#}@export(comptime name: []const u8, target: var, linkage: builtin.GlobalLinkage) void{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@export(target: var, comptime options: std.builtin.ExportOptions) void{#endsyntax#}</pre>
|
||||
<p>
|
||||
Creates a symbol in the output object file.
|
||||
</p>
|
||||
<p>
|
||||
This function can be called from a {#link|comptime#} block to conditionally export symbols.
|
||||
When {#syntax#}target{#endsyntax#} is a function with the C calling convention and
|
||||
{#syntax#}linkage{#endsyntax#} is {#syntax#}Strong{#endsyntax#}, this is equivalent to
|
||||
{#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#}
|
||||
const builtin = @import("builtin");
|
||||
|
||||
comptime {
|
||||
@export("foo", internalName, builtin.GlobalLinkage.Strong);
|
||||
@export(internalName, .{ .name = "foo", .linkage = .Strong });
|
||||
}
|
||||
|
||||
extern fn internalName() void {}
|
||||
@@ -7077,7 +7432,7 @@ test "field access by string" {
|
||||
<pre>{#syntax#}@frame() *@Frame(func){#endsyntax#}</pre>
|
||||
<p>
|
||||
This function returns a pointer to the frame for a given function. This type
|
||||
can be {#link|implicitly cast|Implicit Casts#} to {#syntax#}anyframe->T{#endsyntax#} and
|
||||
can be {#link|coerced|Type Coercion#} to {#syntax#}anyframe->T{#endsyntax#} and
|
||||
to {#syntax#}anyframe{#endsyntax#}, where {#syntax#}T{#endsyntax#} is the return type
|
||||
of the function in scope.
|
||||
</p>
|
||||
@@ -7101,7 +7456,7 @@ test "field access by string" {
|
||||
const std = @import("std");
|
||||
|
||||
test "heap allocated frame" {
|
||||
const frame = try std.heap.direct_allocator.create(@Frame(func));
|
||||
const frame = try std.heap.page_allocator.create(@Frame(func));
|
||||
frame.* = async func();
|
||||
}
|
||||
|
||||
@@ -7213,27 +7568,6 @@ test "@hasDecl" {
|
||||
{#see_also|Compile Variables|@embedFile#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@inlineCall#}
|
||||
<pre>{#syntax#}@inlineCall(function: X, args: ...) Y{#endsyntax#}</pre>
|
||||
<p>
|
||||
This calls a function, in the same way that invoking an expression with parentheses does:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "inline function call" {
|
||||
assert(@inlineCall(add, 3, 9) == 12);
|
||||
}
|
||||
|
||||
fn add(a: i32, b: i32) i32 { return a + b; }
|
||||
{#code_end#}
|
||||
<p>
|
||||
Unlike a normal function call, however, {#syntax#}@inlineCall{#endsyntax#} guarantees that the call
|
||||
will be inlined. If the call cannot be inlined, a compile error is emitted.
|
||||
</p>
|
||||
{#see_also|@noInlineCall#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@intCast#}
|
||||
<pre>{#syntax#}@intCast(comptime DestType: type, int: var) DestType{#endsyntax#}</pre>
|
||||
<p>
|
||||
@@ -7241,6 +7575,10 @@ fn add(a: i32, b: i32) i32 { return a + b; }
|
||||
Attempting to convert a number which is out of range of the destination type results in
|
||||
safety-protected {#link|Undefined Behavior#}.
|
||||
</p>
|
||||
<p>
|
||||
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
|
||||
then this is semantically equivalent to {#link|Type Coercion#}.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@intToEnum#}
|
||||
@@ -7387,71 +7725,6 @@ mem.set(u8, dest, c);{#endsyntax#}</pre>
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@newStackCall#}
|
||||
<pre>{#syntax#}@newStackCall(new_stack: []align(target_stack_align) u8, function: var, args: ...) var{#endsyntax#}</pre>
|
||||
<p>
|
||||
This calls a function, in the same way that invoking an expression with parentheses does. However,
|
||||
instead of using the same stack as the caller, the function uses the stack provided in the {#syntax#}new_stack{#endsyntax#}
|
||||
parameter.
|
||||
</p>
|
||||
<p>
|
||||
The new stack must be aligned to {#syntax#}target_stack_align{#endsyntax#} bytes. This is a target-specific
|
||||
number. A safe value that will work on all targets is {#syntax#}16{#endsyntax#}. This value can
|
||||
also be obtained by using {#link|@sizeOf#} on the {#link|@Frame#} type of {#link|Async Functions#}.
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
var new_stack_bytes: [1024]u8 align(16) = undefined;
|
||||
|
||||
test "calling a function with a new stack" {
|
||||
const arg = 1234;
|
||||
|
||||
const a = @newStackCall(new_stack_bytes[0..512], targetFunction, arg);
|
||||
const b = @newStackCall(new_stack_bytes[512..], targetFunction, arg);
|
||||
_ = targetFunction(arg);
|
||||
|
||||
assert(arg == 1234);
|
||||
assert(a < b);
|
||||
}
|
||||
|
||||
fn targetFunction(x: i32) usize {
|
||||
assert(x == 1234);
|
||||
|
||||
var local_variable: i32 = 42;
|
||||
const ptr = &local_variable;
|
||||
ptr.* += 1;
|
||||
|
||||
assert(local_variable == 43);
|
||||
return @ptrToInt(ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@noInlineCall#}
|
||||
<pre>{#syntax#}@noInlineCall(function: var, args: ...) var{#endsyntax#}</pre>
|
||||
<p>
|
||||
This calls a function, in the same way that invoking an expression with parentheses does:
|
||||
</p>
|
||||
{#code_begin|test#}
|
||||
const assert = @import("std").debug.assert;
|
||||
|
||||
test "noinline function call" {
|
||||
assert(@noInlineCall(add, 3, 9) == 12);
|
||||
}
|
||||
|
||||
fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
Unlike a normal function call, however, {#syntax#}@noInlineCall{#endsyntax#} guarantees that the call
|
||||
will not be inlined. If the call must be inlined, a compile error is emitted.
|
||||
</p>
|
||||
{#see_also|@inlineCall#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@OpaqueType#}
|
||||
<pre>{#syntax#}@OpaqueType() type{#endsyntax#}</pre>
|
||||
<p>
|
||||
@@ -7466,7 +7739,7 @@ const Derp = @OpaqueType();
|
||||
const Wat = @OpaqueType();
|
||||
|
||||
extern fn bar(d: *Derp) void;
|
||||
export fn foo(w: *Wat) void {
|
||||
fn foo(w: *Wat) callconv(.C) void {
|
||||
bar(w);
|
||||
}
|
||||
|
||||
@@ -7729,7 +8002,7 @@ test "@setRuntimeSafety" {
|
||||
{#syntax#}b{#endsyntax#}. Positive numbers select from {#syntax#}a{#endsyntax#} starting at 0.
|
||||
Negative values select from {#syntax#}b{#endsyntax#}, starting at {#syntax#}-1{#endsyntax#} and going down.
|
||||
It is recommended to use the {#syntax#}~{#endsyntax#} operator from indexes from {#syntax#}b{#endsyntax#}
|
||||
so that both indexes can start from {#syntax#}0{#endsyntax#} (i.e. {#syntax#}~i32(0){#endsyntax#} is
|
||||
so that both indexes can start from {#syntax#}0{#endsyntax#} (i.e. {#syntax#}~@as(i32, 0){#endsyntax#} is
|
||||
{#syntax#}-1{#endsyntax#}).
|
||||
</p>
|
||||
<p>
|
||||
@@ -7783,7 +8056,7 @@ test "@setRuntimeSafety" {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@splat#}
|
||||
<pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @typeOf(scalar)){#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@splat(comptime len: u32, scalar: var) @Vector(len, @TypeOf(scalar)){#endsyntax#}</pre>
|
||||
<p>
|
||||
Produces a vector of length {#syntax#}len{#endsyntax#} where each element is the value
|
||||
{#syntax#}scalar{#endsyntax#}:
|
||||
@@ -7795,8 +8068,8 @@ const assert = std.debug.assert;
|
||||
test "vector @splat" {
|
||||
const scalar: u32 = 5;
|
||||
const result = @splat(4, scalar);
|
||||
comptime assert(@typeOf(result) == @Vector(4, u32));
|
||||
assert(std.mem.eql(u32, ([4]u32)(result), [_]u32{ 5, 5, 5, 5 }));
|
||||
comptime assert(@TypeOf(result) == @Vector(4, u32));
|
||||
assert(std.mem.eql(u32, &@as([4]u32, result), &[_]u32{ 5, 5, 5, 5 }));
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -7807,94 +8080,146 @@ test "vector @splat" {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@sqrt#}
|
||||
<pre>{#syntax#}@sqrt(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@sqrt(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Performs the square root of a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Supports {#syntax#}f16{#endsyntax#}, {#syntax#}f32{#endsyntax#}, {#syntax#}f64{#endsyntax#}, and {#syntax#}f128{#endsyntax#}, as well as vectors.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@sin#}
|
||||
<pre>{#syntax#}@sin(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@sin(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Sine trigometric function on a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@cos#}
|
||||
<pre>{#syntax#}@cos(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@cos(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@exp#}
|
||||
<pre>{#syntax#}@exp(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@exp(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Base-e exponential function on a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@exp2#}
|
||||
<pre>{#syntax#}@exp2(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@exp2(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@ln#}
|
||||
<pre>{#syntax#}@ln(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
{#header_open|@log#}
|
||||
<pre>{#syntax#}@log(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@log2#}
|
||||
<pre>{#syntax#}@log2(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@log2(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@log10#}
|
||||
<pre>{#syntax#}@log10(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@log10(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@fabs#}
|
||||
<pre>{#syntax#}@fabs(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@fabs(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the absolute value of a floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@floor#}
|
||||
<pre>{#syntax#}@floor(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@floor(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
Returns the largest integral value not greater than the given floating point number.
|
||||
Uses a dedicated hardware instruction when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@ceil#}
|
||||
<pre>{#syntax#}@ceil(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@ceil(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
Returns the largest integral value not less than the given floating point number.
|
||||
Uses a dedicated hardware instruction when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@trunc#}
|
||||
<pre>{#syntax#}@trunc(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@trunc(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
Rounds the given floating point number to an integer, towards zero.
|
||||
Uses a dedicated hardware instruction when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
{#header_open|@round#}
|
||||
<pre>{#syntax#}@round(comptime T: type, value: T) T{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@round(value: var) @TypeOf(value){#endsyntax#}</pre>
|
||||
<p>
|
||||
Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction
|
||||
when available. Currently supports {#syntax#}f32{#endsyntax#} and {#syntax#}f64{#endsyntax#}.
|
||||
when available.
|
||||
</p>
|
||||
<p>
|
||||
Supports {#link|Floats#} and {#link|Vectors#} of floats, with the caveat that
|
||||
<a href="https://github.com/ziglang/zig/issues/4026">some float operations are not yet implemented for all float types</a>.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
@@ -7992,10 +8317,6 @@ test "integer truncation" {
|
||||
This function always truncates the significant bits of the integer, regardless
|
||||
of endianness on the target platform.
|
||||
</p>
|
||||
<p>
|
||||
If {#syntax#}T{#endsyntax#} is {#syntax#}comptime_int{#endsyntax#},
|
||||
then this is semantically equivalent to an {#link|implicit cast|Implicit Casts#}.
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@Type#}
|
||||
@@ -8012,13 +8333,13 @@ test "integer truncation" {
|
||||
<li>{#syntax#}noreturn{#endsyntax#}</li>
|
||||
<li>{#syntax#}void{#endsyntax#}</li>
|
||||
<li>{#syntax#}bool{#endsyntax#}</li>
|
||||
<li>{#link|Integers#}</li> - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.
|
||||
<li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li>
|
||||
<li>{#link|Floats#}</li>
|
||||
<li>{#link|Pointers#}</li>
|
||||
<li>{#syntax#}comptime_int{#endsyntax#}</li>
|
||||
<li>{#syntax#}comptime_float{#endsyntax#}</li>
|
||||
<li>{#syntax#}@typeOf(undefined){#endsyntax#}</li>
|
||||
<li>{#syntax#}@typeOf(null){#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li>
|
||||
<li>{#syntax#}@TypeOf(null){#endsyntax#}</li>
|
||||
</ul>
|
||||
<p>
|
||||
For these types it is a
|
||||
@@ -8044,7 +8365,6 @@ test "integer truncation" {
|
||||
<li>{#link|union#}</li>
|
||||
<li>{#link|Functions#}</li>
|
||||
<li>BoundFn</li>
|
||||
<li>ArgTuple</li>
|
||||
<li>{#link|struct#}</li>
|
||||
</ul>
|
||||
{#header_close#}
|
||||
@@ -8071,205 +8391,25 @@ pub const TypeId = enum {
|
||||
Null,
|
||||
Optional,
|
||||
ErrorUnion,
|
||||
Error,
|
||||
ErrorSet,
|
||||
Enum,
|
||||
Union,
|
||||
Fn,
|
||||
Block,
|
||||
BoundFn,
|
||||
ArgTuple,
|
||||
Opaque,
|
||||
Frame,
|
||||
AnyFrame,
|
||||
Vector,
|
||||
EnumLiteral,
|
||||
};
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@typeInfo#}
|
||||
<pre>{#syntax#}@typeInfo(comptime T: type) @import("builtin").TypeInfo{#endsyntax#}</pre>
|
||||
<pre>{#syntax#}@typeInfo(comptime T: type) @import("std").builtin.TypeInfo{#endsyntax#}</pre>
|
||||
<p>
|
||||
Returns information on the type. Returns a value of the following union:
|
||||
Provides type reflection.
|
||||
</p>
|
||||
{#code_begin|syntax#}
|
||||
pub const TypeInfo = union(TypeId) {
|
||||
Type: void,
|
||||
Void: void,
|
||||
Bool: void,
|
||||
NoReturn: void,
|
||||
Int: Int,
|
||||
Float: Float,
|
||||
Pointer: Pointer,
|
||||
Array: Array,
|
||||
Struct: Struct,
|
||||
ComptimeFloat: void,
|
||||
ComptimeInt: void,
|
||||
Undefined: void,
|
||||
Null: void,
|
||||
Optional: Optional,
|
||||
ErrorUnion: ErrorUnion,
|
||||
ErrorSet: ErrorSet,
|
||||
Enum: Enum,
|
||||
Union: Union,
|
||||
Fn: Fn,
|
||||
BoundFn: Fn,
|
||||
ArgTuple: void,
|
||||
Opaque: void,
|
||||
Promise: Promise,
|
||||
Vector: Vector,
|
||||
EnumLiteral: void,
|
||||
|
||||
|
||||
pub const Int = struct {
|
||||
is_signed: bool,
|
||||
bits: comptime_int,
|
||||
};
|
||||
|
||||
pub const Float = struct {
|
||||
bits: comptime_int,
|
||||
};
|
||||
|
||||
pub const Pointer = struct {
|
||||
size: Size,
|
||||
is_const: bool,
|
||||
is_volatile: bool,
|
||||
alignment: comptime_int,
|
||||
child: type,
|
||||
is_allowzero: bool,
|
||||
|
||||
pub const Size = enum {
|
||||
One,
|
||||
Many,
|
||||
Slice,
|
||||
C,
|
||||
};
|
||||
};
|
||||
|
||||
pub const Array = struct {
|
||||
len: comptime_int,
|
||||
child: type,
|
||||
};
|
||||
|
||||
pub const ContainerLayout = enum {
|
||||
Auto,
|
||||
Extern,
|
||||
Packed,
|
||||
};
|
||||
|
||||
pub const StructField = struct {
|
||||
name: []const u8,
|
||||
offset: ?comptime_int,
|
||||
field_type: type,
|
||||
};
|
||||
|
||||
pub const Struct = struct {
|
||||
layout: ContainerLayout,
|
||||
fields: []StructField,
|
||||
decls: []Declaration,
|
||||
};
|
||||
|
||||
pub const Optional = struct {
|
||||
child: type,
|
||||
};
|
||||
|
||||
pub const ErrorUnion = struct {
|
||||
error_set: type,
|
||||
payload: type,
|
||||
};
|
||||
|
||||
pub const Error = struct {
|
||||
name: []const u8,
|
||||
value: comptime_int,
|
||||
};
|
||||
|
||||
pub const ErrorSet = ?[]Error;
|
||||
|
||||
pub const EnumField = struct {
|
||||
name: []const u8,
|
||||
value: comptime_int,
|
||||
};
|
||||
|
||||
pub const Enum = struct {
|
||||
layout: ContainerLayout,
|
||||
tag_type: type,
|
||||
fields: []EnumField,
|
||||
decls: []Declaration,
|
||||
};
|
||||
|
||||
pub const UnionField = struct {
|
||||
name: []const u8,
|
||||
enum_field: ?EnumField,
|
||||
field_type: type,
|
||||
};
|
||||
|
||||
pub const Union = struct {
|
||||
layout: ContainerLayout,
|
||||
tag_type: ?type,
|
||||
fields: []UnionField,
|
||||
decls: []Declaration,
|
||||
};
|
||||
|
||||
pub const CallingConvention = enum {
|
||||
Unspecified,
|
||||
C,
|
||||
Cold,
|
||||
Naked,
|
||||
Stdcall,
|
||||
Async,
|
||||
};
|
||||
|
||||
pub const FnArg = struct {
|
||||
is_generic: bool,
|
||||
is_noalias: bool,
|
||||
arg_type: ?type,
|
||||
};
|
||||
|
||||
pub const Fn = struct {
|
||||
calling_convention: CallingConvention,
|
||||
is_generic: bool,
|
||||
is_var_args: bool,
|
||||
return_type: ?type,
|
||||
async_allocator_type: ?type,
|
||||
args: []FnArg,
|
||||
};
|
||||
|
||||
pub const Promise = struct {
|
||||
child: ?type,
|
||||
};
|
||||
|
||||
pub const Vector = struct {
|
||||
len: comptime_int,
|
||||
child: type,
|
||||
};
|
||||
|
||||
pub const Declaration = struct {
|
||||
name: []const u8,
|
||||
is_pub: bool,
|
||||
data: Data,
|
||||
|
||||
pub const Data = union(enum) {
|
||||
Type: type,
|
||||
Var: type,
|
||||
Fn: FnDecl,
|
||||
|
||||
pub const FnDecl = struct {
|
||||
fn_type: type,
|
||||
inline_type: Inline,
|
||||
calling_convention: CallingConvention,
|
||||
is_var_args: bool,
|
||||
is_extern: bool,
|
||||
is_export: bool,
|
||||
lib_name: ?[]const u8,
|
||||
return_type: type,
|
||||
arg_names: [][] const u8,
|
||||
|
||||
pub const Inline = enum {
|
||||
Auto,
|
||||
Always,
|
||||
Never,
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
{#code_end#}
|
||||
<p>
|
||||
For {#link|structs|struct#}, {#link|unions|union#}, {#link|enums|enum#}, and
|
||||
{#link|error sets|Error Set Type#}, the fields are guaranteed to be in the same
|
||||
@@ -8286,20 +8426,20 @@ pub const TypeInfo = union(TypeId) {
|
||||
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|@typeOf#}
|
||||
<pre>{#syntax#}@typeOf(expression) type{#endsyntax#}</pre>
|
||||
{#header_open|@TypeOf#}
|
||||
<pre>{#syntax#}@TypeOf(expression) type{#endsyntax#}</pre>
|
||||
<p>
|
||||
This function returns a compile-time constant, which is the type of the
|
||||
expression passed as an argument. The expression is evaluated.
|
||||
</p>
|
||||
<p>{#syntax#}@typeOf{#endsyntax#} guarantees no run-time side-effects within the expression:</p>
|
||||
<p>{#syntax#}@TypeOf{#endsyntax#} guarantees no run-time side-effects within the expression:</p>
|
||||
{#code_begin|test#}
|
||||
const std = @import("std");
|
||||
const assert = std.debug.assert;
|
||||
|
||||
test "no runtime side effects" {
|
||||
var data: i32 = 0;
|
||||
const T = @typeOf(foo(i32, &data));
|
||||
const T = @TypeOf(foo(i32, &data));
|
||||
comptime assert(T == i32);
|
||||
assert(data == 0);
|
||||
}
|
||||
@@ -8406,7 +8546,7 @@ pub fn build(b: *Builder) void {
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Single Threaded Builds#}
|
||||
<p>Zig has a compile option <code>--single-threaded</code> which has the following effects:
|
||||
<p>Zig has a compile option <code>--single-threaded</code> which has the following effects:</p>
|
||||
<ul>
|
||||
<li>All {#link|Thread Local Variables#} are treated as {#link|Global Variables#}.</li>
|
||||
<li>The overhead of {#link|Async Functions#} becomes equivalent to function call overhead.</li>
|
||||
@@ -8415,7 +8555,6 @@ pub fn build(b: *Builder) void {
|
||||
For example {#syntax#}std.Mutex{#endsyntax#} becomes
|
||||
an empty data structure and all of its functions become no-ops.</li>
|
||||
</ul>
|
||||
</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Undefined Behavior#}
|
||||
@@ -8459,7 +8598,7 @@ pub fn main() void {
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|index 5 outside array of size 5#}
|
||||
comptime {
|
||||
const array = "hello";
|
||||
const array: [5]u8 = "hello".*;
|
||||
const garbage = array[5];
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -8489,7 +8628,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var value: i32 = -1;
|
||||
var unsigned = @intCast(u32, value);
|
||||
std.debug.warn("value: {}\n", unsigned);
|
||||
std.debug.warn("value: {}\n", .{unsigned});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -8498,7 +8637,7 @@ pub fn main() void {
|
||||
{#header_close#}
|
||||
{#header_open|Cast Truncates Data#}
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|integer value 300 cannot be implicitly casted to type 'u8'#}
|
||||
{#code_begin|test_err|integer value 300 cannot be coerced to type 'u8'#}
|
||||
comptime {
|
||||
const spartan_count: u16 = 300;
|
||||
const byte = @intCast(u8, spartan_count);
|
||||
@@ -8511,7 +8650,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var spartan_count: u16 = 300;
|
||||
const byte = @intCast(u8, spartan_count);
|
||||
std.debug.warn("value: {}\n", byte);
|
||||
std.debug.warn("value: {}\n", .{byte});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -8545,7 +8684,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var byte: u8 = 255;
|
||||
byte += 1;
|
||||
std.debug.warn("value: {}\n", byte);
|
||||
std.debug.warn("value: {}\n", .{byte});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8568,11 +8707,11 @@ pub fn main() !void {
|
||||
var byte: u8 = 255;
|
||||
|
||||
byte = if (math.add(u8, byte, 1)) |result| result else |err| {
|
||||
warn("unable to add one: {}\n", @errorName(err));
|
||||
warn("unable to add one: {}\n", .{@errorName(err)});
|
||||
return err;
|
||||
};
|
||||
|
||||
warn("result: {}\n", byte);
|
||||
warn("result: {}\n", .{byte});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8597,9 +8736,9 @@ pub fn main() void {
|
||||
|
||||
var result: u8 = undefined;
|
||||
if (@addWithOverflow(u8, byte, 10, &result)) {
|
||||
warn("overflowed result: {}\n", result);
|
||||
warn("overflowed result: {}\n", .{result});
|
||||
} else {
|
||||
warn("result: {}\n", result);
|
||||
warn("result: {}\n", .{result});
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -8634,7 +8773,7 @@ test "wraparound addition and subtraction" {
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|operation caused overflow#}
|
||||
comptime {
|
||||
const x = @shlExact(u8(0b01010101), 2);
|
||||
const x = @shlExact(@as(u8, 0b01010101), 2);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>At runtime:</p>
|
||||
@@ -8644,7 +8783,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var x: u8 = 0b01010101;
|
||||
var y = @shlExact(x, 2);
|
||||
std.debug.warn("value: {}\n", y);
|
||||
std.debug.warn("value: {}\n", .{y});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8652,7 +8791,7 @@ pub fn main() void {
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|exact shift shifted out 1 bits#}
|
||||
comptime {
|
||||
const x = @shrExact(u8(0b10101010), 2);
|
||||
const x = @shrExact(@as(u8, 0b10101010), 2);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>At runtime:</p>
|
||||
@@ -8662,7 +8801,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var x: u8 = 0b10101010;
|
||||
var y = @shrExact(x, 2);
|
||||
std.debug.warn("value: {}\n", y);
|
||||
std.debug.warn("value: {}\n", .{y});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8683,7 +8822,7 @@ pub fn main() void {
|
||||
var a: u32 = 1;
|
||||
var b: u32 = 0;
|
||||
var c = a / b;
|
||||
std.debug.warn("value: {}\n", c);
|
||||
std.debug.warn("value: {}\n", .{c});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8704,7 +8843,7 @@ pub fn main() void {
|
||||
var a: u32 = 10;
|
||||
var b: u32 = 0;
|
||||
var c = a % b;
|
||||
std.debug.warn("value: {}\n", c);
|
||||
std.debug.warn("value: {}\n", .{c});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8725,7 +8864,7 @@ pub fn main() void {
|
||||
var a: u32 = 10;
|
||||
var b: u32 = 3;
|
||||
var c = @divExact(a, b);
|
||||
std.debug.warn("value: {}\n", c);
|
||||
std.debug.warn("value: {}\n", .{c});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8734,7 +8873,7 @@ pub fn main() void {
|
||||
{#code_begin|test_err|unable to convert#}
|
||||
comptime {
|
||||
var bytes = [5]u8{ 1, 2, 3, 4, 5 };
|
||||
var slice = @bytesToSlice(u32, bytes);
|
||||
var slice = @bytesToSlice(u32, bytes[0..]);
|
||||
}
|
||||
{#code_end#}
|
||||
<p>At runtime:</p>
|
||||
@@ -8744,7 +8883,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var bytes = [5]u8{ 1, 2, 3, 4, 5 };
|
||||
var slice = @bytesToSlice(u32, bytes[0..]);
|
||||
std.debug.warn("value: {}\n", slice[0]);
|
||||
std.debug.warn("value: {}\n", .{slice[0]});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8763,7 +8902,7 @@ const std = @import("std");
|
||||
pub fn main() void {
|
||||
var optional_number: ?i32 = null;
|
||||
var number = optional_number.?;
|
||||
std.debug.warn("value: {}\n", number);
|
||||
std.debug.warn("value: {}\n", .{number});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>One way to avoid this crash is to test for null instead of assuming non-null, with
|
||||
@@ -8774,9 +8913,9 @@ pub fn main() void {
|
||||
const optional_number: ?i32 = null;
|
||||
|
||||
if (optional_number) |number| {
|
||||
warn("got number: {}\n", number);
|
||||
warn("got number: {}\n", .{number});
|
||||
} else {
|
||||
warn("it's null\n");
|
||||
warn("it's null\n", .{});
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -8799,7 +8938,7 @@ const std = @import("std");
|
||||
|
||||
pub fn main() void {
|
||||
const number = getNumberOrFail() catch unreachable;
|
||||
std.debug.warn("value: {}\n", number);
|
||||
std.debug.warn("value: {}\n", .{number});
|
||||
}
|
||||
|
||||
fn getNumberOrFail() !i32 {
|
||||
@@ -8815,9 +8954,9 @@ pub fn main() void {
|
||||
const result = getNumberOrFail();
|
||||
|
||||
if (result) |number| {
|
||||
warn("got number: {}\n", number);
|
||||
warn("got number: {}\n", .{number});
|
||||
} else |err| {
|
||||
warn("got error: {}\n", @errorName(err));
|
||||
warn("got error: {}\n", .{@errorName(err)});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8844,7 +8983,7 @@ pub fn main() void {
|
||||
var err = error.AnError;
|
||||
var number = @errorToInt(err) + 500;
|
||||
var invalid_err = @intToError(number);
|
||||
std.debug.warn("value: {}\n", number);
|
||||
std.debug.warn("value: {}\n", .{number});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8874,7 +9013,7 @@ const Foo = enum {
|
||||
pub fn main() void {
|
||||
var a: u2 = 3;
|
||||
var b = @intToEnum(Foo, a);
|
||||
std.debug.warn("value: {}\n", @tagName(b));
|
||||
std.debug.warn("value: {}\n", .{@tagName(b)});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8911,7 +9050,7 @@ pub fn main() void {
|
||||
}
|
||||
fn foo(set1: Set1) void {
|
||||
const x = @errSetCast(Set2, set1);
|
||||
std.debug.warn("value: {}\n", x);
|
||||
std.debug.warn("value: {}\n", .{x});
|
||||
}
|
||||
{#code_end#}
|
||||
{#header_close#}
|
||||
@@ -8920,7 +9059,7 @@ fn foo(set1: Set1) void {
|
||||
<p>At compile-time:</p>
|
||||
{#code_begin|test_err|pointer address 0x1 is not aligned to 4 bytes#}
|
||||
comptime {
|
||||
const ptr = @intToPtr(*i32, 0x1);
|
||||
const ptr = @intToPtr(*align(1) i32, 0x1);
|
||||
const aligned = @alignCast(4, ptr);
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -8967,7 +9106,7 @@ pub fn main() void {
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
f.float = 12.34;
|
||||
std.debug.warn("value: {}\n", f.float);
|
||||
std.debug.warn("value: {}\n", .{f.float});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -8991,7 +9130,7 @@ pub fn main() void {
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
f.* = Foo{ .float = 12.34 };
|
||||
std.debug.warn("value: {}\n", f.float);
|
||||
std.debug.warn("value: {}\n", .{f.float});
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -9010,7 +9149,7 @@ pub fn main() void {
|
||||
var f = Foo{ .int = 42 };
|
||||
f = Foo{ .float = undefined };
|
||||
bar(&f);
|
||||
std.debug.warn("value: {}\n", f.float);
|
||||
std.debug.warn("value: {}\n", .{f.float});
|
||||
}
|
||||
|
||||
fn bar(f: *Foo) void {
|
||||
@@ -9110,8 +9249,6 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
|
||||
</li>
|
||||
<li>Are you linking libc? In this case, {#syntax#}std.heap.c_allocator{#endsyntax#} is likely
|
||||
the right choice, at least for your main allocator.</li>
|
||||
<li>Are you building for WebAssembly? In this case, {#syntax#}std.heap.wasm_allocator{#endsyntax#} is likely
|
||||
the right choice for your main allocator as it uses WebAssembly's memory instructions.</li>
|
||||
<li>
|
||||
Is the maximum number of bytes that you will need bounded by a number known at
|
||||
{#link|comptime#}? In this case, use {#syntax#}std.heap.FixedBufferAllocator{#endsyntax#} or
|
||||
@@ -9127,13 +9264,13 @@ fn concat(allocator: *Allocator, a: []const u8, b: []const u8) ![]u8 {
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator);
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
|
||||
const allocator = &arena.allocator;
|
||||
|
||||
const ptr = try allocator.create(i32);
|
||||
std.debug.warn("ptr={*}\n", ptr);
|
||||
std.debug.warn("ptr={*}\n", .{ptr});
|
||||
}
|
||||
{#code_end#}
|
||||
When using this kind of allocator, there is no need to free anything manually. Everything
|
||||
@@ -9198,7 +9335,7 @@ test "string literal to constant slice" {
|
||||
The location of memory allocated with {#syntax#}allocator.alloc{#endsyntax#} or
|
||||
{#syntax#}allocator.create{#endsyntax#} is determined by the allocator's implementation.
|
||||
</p>
|
||||
</p>TODO: thread local variables</p>
|
||||
<p>TODO: thread local variables</p>
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Implementing an Allocator#}
|
||||
@@ -9435,22 +9572,6 @@ test "assert in release fast mode" {
|
||||
</ul>
|
||||
{#see_also|Primitive Types#}
|
||||
{#header_close#}
|
||||
{#header_open|C String Literals#}
|
||||
{#code_begin|exe#}
|
||||
{#link_libc#}
|
||||
extern fn puts([*]const u8) void;
|
||||
|
||||
pub fn main() void {
|
||||
puts(c"this has a null terminator");
|
||||
puts(
|
||||
c\\and so
|
||||
c\\does this
|
||||
c\\multiline C string literal
|
||||
);
|
||||
}
|
||||
{#code_end#}
|
||||
{#see_also|String Literals and Character Literals#}
|
||||
{#header_close#}
|
||||
|
||||
{#header_open|Import from C Header File#}
|
||||
<p>
|
||||
@@ -9465,7 +9586,7 @@ const c = @cImport({
|
||||
@cInclude("stdio.h");
|
||||
});
|
||||
pub fn main() void {
|
||||
_ = c.printf(c"hello\n");
|
||||
_ = c.printf("hello\n");
|
||||
}
|
||||
{#code_end#}
|
||||
<p>
|
||||
@@ -9504,8 +9625,8 @@ const c = @cImport({
|
||||
<p>{#syntax#}[*c]T{#endsyntax#} - C pointer.</p>
|
||||
<ul>
|
||||
<li>Supports all the syntax of the other two pointer types.</li>
|
||||
<li>Implicitly casts to other pointer types, as well as {#link|Optional Pointers#}.
|
||||
When a C pointer is implicitly casted to a non-optional pointer, safety-checked
|
||||
<li>Coerces to other pointer types, as well as {#link|Optional Pointers#}.
|
||||
When a C pointer is coerced to a non-optional pointer, safety-checked
|
||||
{#link|Undefined Behavior#} occurs if the address is 0.
|
||||
</li>
|
||||
<li>Allows address 0. On non-freestanding targets, dereferencing address 0 is safety-checked
|
||||
@@ -9513,7 +9634,7 @@ const c = @cImport({
|
||||
null, just like {#syntax#}?usize{#endsyntax#}. Note that creating an optional C pointer
|
||||
is unnecessary as one can use normal {#link|Optional Pointers#}.
|
||||
</li>
|
||||
<li>Supports {#link|implicit casting|Implicit Casts#} to and from integers.</li>
|
||||
<li>Supports {#link|Type Coercion#} to and from integers.</li>
|
||||
<li>Supports comparison with integers.</li>
|
||||
<li>Does not support Zig-only pointer attributes such as alignment. Use normal {#link|Pointers#}
|
||||
please!</li>
|
||||
@@ -9564,7 +9685,7 @@ pub fn build(b: *Builder) void {
|
||||
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
|
||||
|
||||
const exe = b.addExecutable("test", null);
|
||||
exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"});
|
||||
exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
|
||||
exe.linkLibrary(lib);
|
||||
exe.linkSystemLibrary("c");
|
||||
|
||||
@@ -9629,7 +9750,7 @@ pub fn build(b: *Builder) void {
|
||||
const obj = b.addObject("base64", "base64.zig");
|
||||
|
||||
const exe = b.addExecutable("test", null);
|
||||
exe.addCSourceFile("test.c", [_][]const u8{"-std=c99"});
|
||||
exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
|
||||
exe.addObject(obj);
|
||||
exe.linkSystemLibrary("c");
|
||||
exe.install();
|
||||
@@ -9643,8 +9764,7 @@ all your base are belong to us</code></pre>
|
||||
{#header_close#}
|
||||
{#header_close#}
|
||||
{#header_open|WebAssembly#}
|
||||
<p>Zig supports building for WebAssembly out of the box. There is also a specialized {#syntax#}std.heap.wasm_allocator{#endsyntax#}
|
||||
memory allocator for WebAssembly environments.</p>
|
||||
<p>Zig supports building for WebAssembly out of the box.</p>
|
||||
{#header_open|Freestanding#}
|
||||
<p>For host environments like the web browser and nodejs, build as a library using the freestanding OS target.
|
||||
Here's an example of running Zig code compiled to WebAssembly with nodejs.</p>
|
||||
@@ -9678,11 +9798,12 @@ The result is 3</code></pre>
|
||||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
const args = try std.process.argsAlloc(std.heap.wasm_allocator);
|
||||
defer std.process.argsFree(std.heap.wasm_allocator, args);
|
||||
// TODO a better default allocator that isn't as wasteful!
|
||||
const args = try std.process.argsAlloc(std.heap.page_allocator);
|
||||
defer std.process.argsFree(std.heap.page_allocator, args);
|
||||
|
||||
for (args) |arg, i| {
|
||||
std.debug.warn("{}: {}\n", i, arg);
|
||||
std.debug.warn("{}: {}\n", .{i, arg});
|
||||
}
|
||||
}
|
||||
{#code_end#}
|
||||
@@ -10063,7 +10184,7 @@ fn readU32Be() u32 {}
|
||||
<li>Ascii control characters, except for U+000a (LF): U+0000 - U+0009, U+000b - U+0001f, U+007f. (Note that Windows line endings (CRLF) are not allowed, and hard tabs are not allowed.)</li>
|
||||
<li>Non-Ascii Unicode line endings: U+0085 (NEL), U+2028 (LS), U+2029 (PS).</li>
|
||||
</ul>
|
||||
<p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possbly the last line of the file).</p>
|
||||
<p>The codepoint U+000a (LF) (which is encoded as the single-byte value 0x0a) is the line terminator character. This character always terminates a line of zig source code (except possibly the last line of the file).</p>
|
||||
<p>For some discussion on the rationale behind these design decisions, see <a href="https://github.com/ziglang/zig/issues/663">issue #663</a></p>
|
||||
{#header_close#}
|
||||
|
||||
@@ -10087,18 +10208,18 @@ ContainerMembers
|
||||
<- TestDecl ContainerMembers
|
||||
/ TopLevelComptime ContainerMembers
|
||||
/ KEYWORD_pub? TopLevelDecl ContainerMembers
|
||||
/ KEYWORD_pub? ContainerField COMMA ContainerMembers
|
||||
/ KEYWORD_pub? ContainerField
|
||||
/ ContainerField COMMA ContainerMembers
|
||||
/ ContainerField
|
||||
/
|
||||
|
||||
TestDecl <- KEYWORD_test STRINGLITERAL Block
|
||||
TestDecl <- KEYWORD_test STRINGLITERALSINGLE Block
|
||||
|
||||
TopLevelComptime <- KEYWORD_comptime BlockExpr
|
||||
|
||||
TopLevelDecl
|
||||
<- (KEYWORD_export / KEYWORD_extern STRINGLITERAL? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
|
||||
/ (KEYWORD_export / KEYWORD_extern STRINGLITERAL?)? KEYWORD_threadlocal? VarDecl
|
||||
/ KEYWORD_use Expr SEMICOLON
|
||||
<- (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE? / KEYWORD_inline)? FnProto (SEMICOLON / Block)
|
||||
/ (KEYWORD_export / KEYWORD_extern STRINGLITERALSINGLE?)? KEYWORD_threadlocal? VarDecl
|
||||
/ KEYWORD_usingnamespace Expr SEMICOLON
|
||||
|
||||
FnProto <- FnCC? KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? LinkSection? EXCLAMATIONMARK? (KEYWORD_var / TypeExpr)
|
||||
|
||||
@@ -10203,6 +10324,7 @@ PrimaryTypeExpr
|
||||
/ CHAR_LITERAL
|
||||
/ ContainerDecl
|
||||
/ DOT IDENTIFIER
|
||||
/ DOT InitList
|
||||
/ ErrorSetDecl
|
||||
/ FLOAT
|
||||
/ FnProto
|
||||
@@ -10268,9 +10390,7 @@ LinkSection <- KEYWORD_linksection LPAREN Expr RPAREN
|
||||
|
||||
# Fn specific
|
||||
FnCC
|
||||
<- KEYWORD_nakedcc
|
||||
/ KEYWORD_stdcallcc
|
||||
/ KEYWORD_extern
|
||||
<- KEYWORD_extern
|
||||
/ KEYWORD_async
|
||||
|
||||
ParamDecl <- (KEYWORD_noalias / KEYWORD_comptime)? (IDENTIFIER COLON)? ParamType
|
||||
@@ -10428,7 +10548,6 @@ string_char
|
||||
|
||||
line_comment <- '//'[^\n]*
|
||||
line_string <- ("\\\\" [^\n]* [ \n]*)+
|
||||
line_cstring <- ("c\\\\" [^\n]* [ \n]*)+
|
||||
skip <- ([ \n] / line_comment)*
|
||||
|
||||
CHAR_LITERAL <- "'" char_char "'" skip
|
||||
@@ -10442,12 +10561,12 @@ INTEGER
|
||||
/ "0o" [0-7]+ skip
|
||||
/ "0x" hex+ skip
|
||||
/ [0-9]+ skip
|
||||
STRINGLITERALSINGLE <- "\"" string_char* "\"" skip
|
||||
STRINGLITERAL
|
||||
<- "c"? "\"" string_char* "\"" skip
|
||||
<- STRINGLITERALSINGLE
|
||||
/ line_string skip
|
||||
/ line_cstring skip
|
||||
IDENTIFIER
|
||||
<- !keyword ("c" !["\\] / [A-Zabd-z_]) [A-Za-z0-9_]* skip
|
||||
<- !keyword [A-Za-z_] [A-Za-z0-9_]* skip
|
||||
/ "@\"" string_char* "\"" skip
|
||||
BUILTINIDENTIFIER <- "@"[A-Za-z_][A-Za-z0-9_]* skip
|
||||
|
||||
@@ -10534,7 +10653,6 @@ KEYWORD_fn <- 'fn' end_of_word
|
||||
KEYWORD_for <- 'for' end_of_word
|
||||
KEYWORD_if <- 'if' end_of_word
|
||||
KEYWORD_inline <- 'inline' end_of_word
|
||||
KEYWORD_nakedcc <- 'nakedcc' end_of_word
|
||||
KEYWORD_noalias <- 'noalias' end_of_word
|
||||
KEYWORD_null <- 'null' end_of_word
|
||||
KEYWORD_or <- 'or' end_of_word
|
||||
@@ -10545,7 +10663,6 @@ KEYWORD_pub <- 'pub' end_of_word
|
||||
KEYWORD_resume <- 'resume' end_of_word
|
||||
KEYWORD_return <- 'return' end_of_word
|
||||
KEYWORD_linksection <- 'linksection' end_of_word
|
||||
KEYWORD_stdcallcc <- 'stdcallcc' end_of_word
|
||||
KEYWORD_struct <- 'struct' end_of_word
|
||||
KEYWORD_suspend <- 'suspend' end_of_word
|
||||
KEYWORD_switch <- 'switch' end_of_word
|
||||
@@ -10567,10 +10684,10 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm
|
||||
/ KEYWORD_defer / KEYWORD_else / KEYWORD_enum / KEYWORD_errdefer
|
||||
/ KEYWORD_error / KEYWORD_export / KEYWORD_extern / KEYWORD_false
|
||||
/ KEYWORD_fn / KEYWORD_for / KEYWORD_if / KEYWORD_inline
|
||||
/ KEYWORD_nakedcc / KEYWORD_noalias / KEYWORD_null / KEYWORD_or
|
||||
/ KEYWORD_noalias / KEYWORD_null / KEYWORD_or
|
||||
/ KEYWORD_orelse / KEYWORD_packed / KEYWORD_promise / KEYWORD_pub
|
||||
/ KEYWORD_resume / KEYWORD_return / KEYWORD_linksection
|
||||
/ KEYWORD_stdcallcc / KEYWORD_struct / KEYWORD_suspend
|
||||
/ KEYWORD_struct / KEYWORD_suspend
|
||||
/ KEYWORD_switch / KEYWORD_test / KEYWORD_threadlocal / KEYWORD_true / KEYWORD_try
|
||||
/ KEYWORD_undefined / KEYWORD_union / KEYWORD_unreachable
|
||||
/ KEYWORD_usingnamespace / KEYWORD_var / KEYWORD_volatile / KEYWORD_while</code></pre>
|
||||
@@ -10591,6 +10708,7 @@ keyword <- KEYWORD_align / KEYWORD_and / KEYWORD_allowzero / KEYWORD_asm
|
||||
<li>Together we serve end users.</li>
|
||||
</ul>
|
||||
{#header_close#}
|
||||
</div></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,391 @@
|
||||
This file contains the copying permission notices for various files in the
|
||||
GNU C Library distribution that have copyright owners other than the Free
|
||||
Software Foundation. These notices all require that a copy of the notice
|
||||
be included in the accompanying documentation and be distributed with
|
||||
binary distributions of the code, so be sure to include this file along
|
||||
with any binary distributions derived from the GNU C Library.
|
||||
|
||||
|
||||
All code incorporated from 4.4 BSD is distributed under the following
|
||||
license:
|
||||
|
||||
Copyright (C) 1991 Regents of the University of California.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. [This condition was removed.]
|
||||
4. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
The DNS resolver code, taken from BIND 4.9.5, is copyrighted by UC
|
||||
Berkeley, by Digital Equipment Corporation and by Internet Software
|
||||
Consortium. The DEC portions are under the following license:
|
||||
|
||||
Portions Copyright (C) 1993 by Digital Equipment Corporation.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies, and
|
||||
that the name of Digital Equipment Corporation not be used in
|
||||
advertising or publicity pertaining to distribution of the document or
|
||||
software without specific, written prior permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ``AS IS'' AND DIGITAL EQUIPMENT CORP.
|
||||
DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
||||
DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
||||
FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
||||
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
||||
WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
The ISC portions are under the following license:
|
||||
|
||||
Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
SOFTWARE.
|
||||
|
||||
The Sun RPC support (from rpcsrc-4.0) is covered by the following
|
||||
license:
|
||||
|
||||
Copyright (c) 2010, Oracle America, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
* Neither the name of the "Oracle America, Inc." nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
The following CMU license covers some of the support code for Mach,
|
||||
derived from Mach 3.0:
|
||||
|
||||
Mach Operating System
|
||||
Copyright (C) 1991,1990,1989 Carnegie Mellon University
|
||||
All Rights Reserved.
|
||||
|
||||
Permission to use, copy, modify and distribute this software and its
|
||||
documentation is hereby granted, provided that both the copyright
|
||||
notice and this permission notice appear in all copies of the
|
||||
software, derivative works or modified versions, and any portions
|
||||
thereof, and that both notices appear in supporting documentation.
|
||||
|
||||
CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS ``AS IS''
|
||||
CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
|
||||
ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
|
||||
Carnegie Mellon requests users of this software to return to
|
||||
|
||||
Software Distribution Coordinator
|
||||
School of Computer Science
|
||||
Carnegie Mellon University
|
||||
Pittsburgh PA 15213-3890
|
||||
|
||||
or Software.Distribution@CS.CMU.EDU any improvements or
|
||||
extensions that they make and grant Carnegie Mellon the rights to
|
||||
redistribute these changes.
|
||||
|
||||
The file if_ppp.h is under the following CMU license:
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the University nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY AND
|
||||
CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
|
||||
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The following license covers the files from Intel's "Highly Optimized
|
||||
Mathematical Functions for Itanium" collection:
|
||||
|
||||
Intel License Agreement
|
||||
|
||||
Copyright (c) 2000, Intel Corporation
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
* The name of Intel Corporation may not be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
The files inet/getnameinfo.c and sysdeps/posix/getaddrinfo.c are copyright
|
||||
(C) by Craig Metz and are distributed under the following license:
|
||||
|
||||
/* The Inner Net License, Version 2.00
|
||||
|
||||
The author(s) grant permission for redistribution and use in source and
|
||||
binary forms, with or without modification, of the software and documentation
|
||||
provided that the following conditions are met:
|
||||
|
||||
0. If you receive a version of the software that is specifically labelled
|
||||
as not being for redistribution (check the version message and/or README),
|
||||
you are not permitted to redistribute that version of the software in any
|
||||
way or form.
|
||||
1. All terms of the all other applicable copyrights and licenses must be
|
||||
followed.
|
||||
2. Redistributions of source code must retain the authors' copyright
|
||||
notice(s), this list of conditions, and the following disclaimer.
|
||||
3. Redistributions in binary form must reproduce the authors' copyright
|
||||
notice(s), this list of conditions, and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
4. [The copyright holder has authorized the removal of this clause.]
|
||||
5. Neither the name(s) of the author(s) nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ITS AUTHORS AND CONTRIBUTORS ``AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
If these license terms cause you a real problem, contact the author. */
|
||||
|
||||
The file sunrpc/des_impl.c is copyright Eric Young:
|
||||
|
||||
Copyright (C) 1992 Eric Young
|
||||
Collected from libdes and modified for SECURE RPC by Martin Kuck 1994
|
||||
This file is distributed under the terms of the GNU Lesser General
|
||||
Public License, version 2.1 or later - see the file COPYING.LIB for details.
|
||||
If you did not receive a copy of the license with this program, please
|
||||
see <http://www.gnu.org/licenses/> to obtain a copy.
|
||||
|
||||
The file inet/rcmd.c is under a UCB copyright and the following:
|
||||
|
||||
Copyright (C) 1998 WIDE Project.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the project nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
The file posix/runtests.c is copyright Tom Lord:
|
||||
|
||||
Copyright 1995 by Tom Lord
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the name of the copyright holder not be
|
||||
used in advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
Tom Lord DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
||||
EVENT SHALL TOM LORD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
||||
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
|
||||
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
The posix/rxspencer tests are copyright Henry Spencer:
|
||||
|
||||
Copyright 1992, 1993, 1994, 1997 Henry Spencer. All rights reserved.
|
||||
This software is not subject to any license of the American Telephone
|
||||
and Telegraph Company or of the Regents of the University of California.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on
|
||||
any computer system, and to alter it and redistribute it, subject
|
||||
to the following restrictions:
|
||||
|
||||
1. The author is not responsible for the consequences of use of this
|
||||
software, no matter how awful, even if they arise from flaws in it.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. Since few users ever read sources,
|
||||
credits must appear in the documentation.
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software. Since few users
|
||||
ever read sources, credits must appear in the documentation.
|
||||
|
||||
4. This notice may not be removed or altered.
|
||||
|
||||
The file posix/PCRE.tests is copyright University of Cambridge:
|
||||
|
||||
Copyright (c) 1997-2003 University of Cambridge
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose on any
|
||||
computer system, and to redistribute it freely, subject to the following
|
||||
restrictions:
|
||||
|
||||
1. This software is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
2. The origin of this software must not be misrepresented, either by
|
||||
explicit claim or by omission. In practice, this means that if you use
|
||||
PCRE in software that you distribute to others, commercially or
|
||||
otherwise, you must put a sentence like this
|
||||
|
||||
Regular expression support is provided by the PCRE library package,
|
||||
which is open source software, written by Philip Hazel, and copyright
|
||||
by the University of Cambridge, England.
|
||||
|
||||
somewhere reasonably visible in your documentation and in any relevant
|
||||
files or online help data or similar. A reference to the ftp site for
|
||||
the source, that is, to
|
||||
|
||||
ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
|
||||
|
||||
should also be given in the documentation. However, this condition is not
|
||||
intended to apply to whole chains of software. If package A includes PCRE,
|
||||
it must acknowledge it, but if package B is software that includes package
|
||||
A, the condition is not imposed on package B (unless it uses PCRE
|
||||
independently).
|
||||
|
||||
3. Altered versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
|
||||
4. If PCRE is embedded in any software that is released under the GNU
|
||||
General Purpose Licence (GPL), or Lesser General Purpose Licence (LGPL),
|
||||
then the terms of that licence shall supersede any condition above with
|
||||
which it is incompatible.
|
||||
|
||||
Files from Sun fdlibm are copyright Sun Microsystems, Inc.:
|
||||
|
||||
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
|
||||
Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
Permission to use, copy, modify, and distribute this
|
||||
software is freely granted, provided that this notice
|
||||
is preserved.
|
||||
|
||||
Various long double libm functions are copyright Stephen L. Moshier:
|
||||
|
||||
Copyright 2001 by Stephen L. Moshier <moshier@na-net.ornl.gov>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
@@ -29,4 +29,12 @@
|
||||
#define HWCAP_SSBS (1 << 28)
|
||||
#define HWCAP_SB (1 << 29)
|
||||
#define HWCAP_PACA (1 << 30)
|
||||
#define HWCAP_PACG (1UL << 31)
|
||||
#define HWCAP_PACG (1UL << 31)
|
||||
|
||||
#define HWCAP2_DCPODP (1 << 0)
|
||||
#define HWCAP2_SVE2 (1 << 1)
|
||||
#define HWCAP2_SVEAES (1 << 2)
|
||||
#define HWCAP2_SVEPMULL (1 << 3)
|
||||
#define HWCAP2_SVEBITPERM (1 << 4)
|
||||
#define HWCAP2_SVESHA3 (1 << 5)
|
||||
#define HWCAP2_SVESM4 (1 << 6)
|
||||
@@ -1,14 +0,0 @@
|
||||
struct ipc_perm {
|
||||
key_t __ipc_perm_key;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uid_t cuid;
|
||||
gid_t cgid;
|
||||
mode_t mode;
|
||||
unsigned short __ipc_perm_seq;
|
||||
|
||||
unsigned long __pad1;
|
||||
unsigned long __pad2;
|
||||
};
|
||||
|
||||
#define IPC_64 0
|
||||
@@ -1,2 +0,0 @@
|
||||
#define _POSIX_V6_LP64_OFF64 1
|
||||
#define _POSIX_V7_LP64_OFF64 1
|
||||
@@ -1,2 +0,0 @@
|
||||
#undef __WORDSIZE
|
||||
#define __WORDSIZE 64
|
||||
@@ -281,6 +281,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_io_setup 0
|
||||
#define SYS_io_destroy 1
|
||||
@@ -564,4 +570,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -50,7 +50,7 @@
|
||||
* On GCC 4.9 we may always include those headers. On older GCCs, we may do it only if CPU
|
||||
* features used by them are enabled, so we need to check macros like __SSE__ or __MMX__ first.
|
||||
*/
|
||||
#if __MINGW_GNUC_PREREQ(4, 9)
|
||||
#if __MINGW_GNUC_PREREQ(4, 9) || defined(__clang__)
|
||||
#define __MINGW_FORCE_SYS_INTRINS
|
||||
#endif
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
||||
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define LONG_BIT 64
|
||||
#define LONG_BIT 32
|
||||
#endif
|
||||
|
||||
#define LONG_MAX 0x7fffffffffffffffL
|
||||
#define LONG_MAX 0x7fffffffL
|
||||
#define LLONG_MAX 0x7fffffffffffffffLL
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _POSIX_V6_ILP32_OFFBIG 1
|
||||
#define _POSIX_V7_ILP32_OFFBIG 1
|
||||
@@ -0,0 +1,3 @@
|
||||
#undef __WORDSIZE
|
||||
#define __WORDSIZE 32
|
||||
/* FIXME */
|
||||
+6
-4
@@ -1,14 +1,16 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
long __unused1;
|
||||
time_t sem_ctime;
|
||||
long __unused2;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
#else
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
unsigned short sem_nsems;
|
||||
#endif
|
||||
time_t __unused3;
|
||||
time_t __unused4;
|
||||
long __unused3;
|
||||
long __unused4;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/* copied from kernel definition, but with padding replaced
|
||||
* by the corresponding correctly-sized userspace types. */
|
||||
|
||||
struct stat {
|
||||
dev_t st_dev;
|
||||
int __st_dev_padding;
|
||||
long __st_ino_truncated;
|
||||
mode_t st_mode;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
dev_t st_rdev;
|
||||
int __st_rdev_padding;
|
||||
off_t st_size;
|
||||
blksize_t st_blksize;
|
||||
blkcnt_t st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
ino_t st_ino;
|
||||
};
|
||||
@@ -381,6 +381,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define __ARM_NR_breakpoint 0x0f0001
|
||||
#define __ARM_NR_cacheflush 0x0f0002
|
||||
@@ -771,4 +777,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -8,6 +8,4 @@ struct ipc_perm {
|
||||
int __ipc_perm_seq;
|
||||
long __pad1;
|
||||
long __pad2;
|
||||
};
|
||||
|
||||
#define IPC_64 0x100
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
#define IPC_STAT 2
|
||||
@@ -1,7 +1,7 @@
|
||||
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
||||
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define LONG_BIT 32
|
||||
#define LONG_BIT 64
|
||||
#endif
|
||||
|
||||
#define LONG_MAX 0x7fffffffL
|
||||
#define LONG_MAX 0x7fffffffffffffffL
|
||||
#define LLONG_MAX 0x7fffffffffffffffLL
|
||||
@@ -8,6 +8,5 @@ struct msqid_ds {
|
||||
msglen_t msg_qbytes;
|
||||
pid_t msg_lspid;
|
||||
pid_t msg_lrpid;
|
||||
unsigned long __pad1;
|
||||
unsigned long __pad2;
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -1,2 +1,2 @@
|
||||
#define _POSIX_V6_ILP32_OFFBIG 1
|
||||
#define _POSIX_V7_ILP32_OFFBIG 1
|
||||
#define _POSIX_V6_LP64_OFF64 1
|
||||
#define _POSIX_V7_LP64_OFF64 1
|
||||
@@ -1,3 +1,2 @@
|
||||
#undef __WORDSIZE
|
||||
#define __WORDSIZE 32
|
||||
/* FIXME */
|
||||
#define __WORDSIZE 64
|
||||
@@ -1,16 +1,14 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t __unused1;
|
||||
time_t sem_ctime;
|
||||
time_t __unused2;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
#else
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
unsigned short sem_nsems;
|
||||
#endif
|
||||
time_t __unused3;
|
||||
time_t __unused4;
|
||||
long __unused3;
|
||||
long __unused4;
|
||||
};
|
||||
@@ -1,21 +1,18 @@
|
||||
/* copied from kernel definition, but with padding replaced
|
||||
* by the corresponding correctly-sized userspace types. */
|
||||
|
||||
struct stat {
|
||||
dev_t st_dev;
|
||||
int __st_dev_padding;
|
||||
long __st_ino_truncated;
|
||||
ino_t st_ino;
|
||||
mode_t st_mode;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
dev_t st_rdev;
|
||||
int __st_rdev_padding;
|
||||
unsigned long __pad;
|
||||
off_t st_size;
|
||||
blksize_t st_blksize;
|
||||
int __pad2;
|
||||
blkcnt_t st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
ino_t st_ino;
|
||||
unsigned __unused[2];
|
||||
};
|
||||
@@ -100,6 +100,11 @@ int posix_fallocate(int, off_t, off_t);
|
||||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define AT_NO_AUTOMOUNT 0x800
|
||||
#define AT_EMPTY_PATH 0x1000
|
||||
#define AT_STATX_SYNC_TYPE 0x6000
|
||||
#define AT_STATX_SYNC_AS_STAT 0x0000
|
||||
#define AT_STATX_FORCE_SYNC 0x2000
|
||||
#define AT_STATX_DONT_SYNC 0x4000
|
||||
#define AT_RECURSIVE 0x8000
|
||||
|
||||
#define FAPPEND O_APPEND
|
||||
#define FFSYNC O_SYNC
|
||||
|
||||
@@ -31,6 +31,9 @@ void globfree(glob_t *);
|
||||
#define GLOB_NOESCAPE 0x40
|
||||
#define GLOB_PERIOD 0x80
|
||||
|
||||
#define GLOB_TILDE 0x1000
|
||||
#define GLOB_TILDE_CHECK 0x4000
|
||||
|
||||
#define GLOB_NOSPACE 1
|
||||
#define GLOB_ABORTED 2
|
||||
#define GLOB_NOMATCH 3
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
#define ETH_P_QINQ2 0x9200
|
||||
#define ETH_P_QINQ3 0x9300
|
||||
#define ETH_P_EDSA 0xDADA
|
||||
#define ETH_P_DSA_8021Q 0xDADB
|
||||
#define ETH_P_IFE 0xED3E
|
||||
#define ETH_P_AF_IUCV 0xFBFB
|
||||
|
||||
|
||||
@@ -18,10 +18,12 @@ extern "C" {
|
||||
|
||||
struct sched_param {
|
||||
int sched_priority;
|
||||
int sched_ss_low_priority;
|
||||
struct timespec sched_ss_repl_period;
|
||||
struct timespec sched_ss_init_budget;
|
||||
int sched_ss_max_repl;
|
||||
int __reserved1;
|
||||
struct {
|
||||
time_t __reserved1;
|
||||
long __reserved2;
|
||||
} __reserved2[2];
|
||||
int __reserved3;
|
||||
};
|
||||
|
||||
int sched_get_priority_max(int);
|
||||
@@ -47,6 +49,7 @@ int sched_yield(void);
|
||||
#define CLONE_FS 0x00000200
|
||||
#define CLONE_FILES 0x00000400
|
||||
#define CLONE_SIGHAND 0x00000800
|
||||
#define CLONE_PIDFD 0x00001000
|
||||
#define CLONE_PTRACE 0x00002000
|
||||
#define CLONE_VFORK 0x00004000
|
||||
#define CLONE_PARENT 0x00008000
|
||||
|
||||
@@ -71,6 +71,11 @@ int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *__restrict, int
|
||||
int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int);
|
||||
int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int, int);
|
||||
|
||||
#if defined(_BSD_SOURCE) || defined(_GNU_SOURCE)
|
||||
int posix_spawn_file_actions_addchdir_np(posix_spawn_file_actions_t *__restrict, const char *__restrict);
|
||||
int posix_spawn_file_actions_addfchdir_np(posix_spawn_file_actions_t *, int);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -152,6 +152,7 @@ int ptsname_r(int, char *, size_t);
|
||||
char *ecvt(double, int, int *, int *);
|
||||
char *fcvt(double, int, int *, int *);
|
||||
char *gcvt(double, int, char *);
|
||||
char *secure_getenv(const char *);
|
||||
struct __locale_struct;
|
||||
float strtof_l(const char *__restrict, char **__restrict, struct __locale_struct *);
|
||||
double strtod_l(const char *__restrict, char **__restrict, struct __locale_struct *);
|
||||
|
||||
@@ -22,6 +22,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include <bits/ipc.h>
|
||||
#include <bits/ipcstat.h>
|
||||
|
||||
#define IPC_CREAT 01000
|
||||
#define IPC_EXCL 02000
|
||||
@@ -29,7 +30,6 @@ extern "C" {
|
||||
|
||||
#define IPC_RMID 0
|
||||
#define IPC_SET 1
|
||||
#define IPC_STAT 2
|
||||
#define IPC_INFO 3
|
||||
|
||||
#define IPC_PRIVATE ((key_t) 0)
|
||||
|
||||
@@ -25,9 +25,9 @@ typedef unsigned long msglen_t;
|
||||
#define MSG_NOERROR 010000
|
||||
#define MSG_EXCEPT 020000
|
||||
|
||||
#define MSG_STAT 11
|
||||
#define MSG_STAT (11 | (IPC_STAT & 0x100))
|
||||
#define MSG_INFO 12
|
||||
#define MSG_STAT_ANY 13
|
||||
#define MSG_STAT_ANY (13 | (IPC_STAT & 0x100))
|
||||
|
||||
struct msginfo {
|
||||
int msgpool, msgmap, msgmax, msgmnb, msgmni, msgssz, msgtql;
|
||||
|
||||
@@ -31,9 +31,9 @@ extern "C" {
|
||||
|
||||
#define _SEM_SEMUN_UNDEFINED 1
|
||||
|
||||
#define SEM_STAT 18
|
||||
#define SEM_STAT (18 | (IPC_STAT & 0x100))
|
||||
#define SEM_INFO 19
|
||||
#define SEM_STAT_ANY 20
|
||||
#define SEM_STAT_ANY (20 | (IPC_STAT & 0x100))
|
||||
|
||||
struct seminfo {
|
||||
int semmap;
|
||||
|
||||
@@ -33,9 +33,9 @@ extern "C" {
|
||||
|
||||
#define SHM_LOCK 11
|
||||
#define SHM_UNLOCK 12
|
||||
#define SHM_STAT 13
|
||||
#define SHM_STAT (13 | (IPC_STAT & 0x100))
|
||||
#define SHM_INFO 14
|
||||
#define SHM_STAT_ANY 15
|
||||
#define SHM_STAT_ANY (15 | (IPC_STAT & 0x100))
|
||||
#define SHM_DEST 01000
|
||||
#define SHM_LOCKED 02000
|
||||
#define SHM_HUGETLB 04000
|
||||
|
||||
@@ -176,6 +176,7 @@ long syscall(long, ...);
|
||||
int execvpe(const char *, char *const [], char *const []);
|
||||
int issetugid(void);
|
||||
int getentropy(void *, size_t);
|
||||
extern int optreset;
|
||||
#endif
|
||||
|
||||
#ifdef _GNU_SOURCE
|
||||
@@ -188,6 +189,7 @@ char *get_current_dir_name(void);
|
||||
int syncfs(int);
|
||||
int euidaccess(const char *, int);
|
||||
int eaccess(const char *, int);
|
||||
ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
|
||||
#endif
|
||||
|
||||
#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _POSIX_V6_ILP32_OFFBIG 1
|
||||
#define _POSIX_V7_ILP32_OFFBIG 1
|
||||
@@ -0,0 +1,11 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
long __unused1;
|
||||
time_t sem_ctime;
|
||||
long __unused2;
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
long __unused3;
|
||||
long __unused4;
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
/* copied from kernel definition, but with padding replaced
|
||||
* by the corresponding correctly-sized userspace types. */
|
||||
|
||||
struct stat {
|
||||
dev_t st_dev;
|
||||
int __st_dev_padding;
|
||||
long __st_ino_truncated;
|
||||
mode_t st_mode;
|
||||
nlink_t st_nlink;
|
||||
uid_t st_uid;
|
||||
gid_t st_gid;
|
||||
dev_t st_rdev;
|
||||
int __st_rdev_padding;
|
||||
off_t st_size;
|
||||
blksize_t st_blksize;
|
||||
blkcnt_t st_blocks;
|
||||
struct timespec st_atim;
|
||||
struct timespec st_mtim;
|
||||
struct timespec st_ctim;
|
||||
ino_t st_ino;
|
||||
};
|
||||
@@ -418,6 +418,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_restart_syscall 0
|
||||
#define SYS_exit 1
|
||||
@@ -836,4 +842,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
||||
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define LONG_BIT 64
|
||||
#define LONG_BIT 32
|
||||
#endif
|
||||
|
||||
#define LONG_MAX 0x7fffffffffffffffL
|
||||
#define LONG_MAX 0x7fffffffL
|
||||
#define LLONG_MAX 0x7fffffffffffffffLL
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _POSIX_V6_ILP32_OFFBIG 1
|
||||
#define _POSIX_V7_ILP32_OFFBIG 1
|
||||
@@ -1,14 +0,0 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t sem_ctime;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
#else
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
unsigned short sem_nsems;
|
||||
#endif
|
||||
time_t __unused3;
|
||||
time_t __unused4;
|
||||
};
|
||||
@@ -400,6 +400,12 @@
|
||||
#define __NR_io_uring_setup 4425
|
||||
#define __NR_io_uring_enter 4426
|
||||
#define __NR_io_uring_register 4427
|
||||
#define __NR_open_tree 4428
|
||||
#define __NR_move_mount 4429
|
||||
#define __NR_fsopen 4430
|
||||
#define __NR_fsconfig 4431
|
||||
#define __NR_fsmount 4432
|
||||
#define __NR_fspick 4433
|
||||
|
||||
#define SYS_syscall 4000
|
||||
#define SYS_exit 4001
|
||||
@@ -802,4 +808,10 @@
|
||||
#define SYS_pidfd_send_signal 4424
|
||||
#define SYS_io_uring_setup 4425
|
||||
#define SYS_io_uring_enter 4426
|
||||
#define SYS_io_uring_register 4427
|
||||
#define SYS_io_uring_register 4427
|
||||
#define SYS_open_tree 4428
|
||||
#define SYS_move_mount 4429
|
||||
#define SYS_fsopen 4430
|
||||
#define SYS_fsconfig 4431
|
||||
#define SYS_fsmount 4432
|
||||
#define SYS_fspick 4433
|
||||
@@ -9,6 +9,4 @@ struct ipc_perm {
|
||||
int __pad1;
|
||||
unsigned long __unused1;
|
||||
unsigned long __unused2;
|
||||
};
|
||||
|
||||
#define IPC_64 0x100
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t sem_ctime;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
#else
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
unsigned short sem_nsems;
|
||||
#endif
|
||||
time_t __unused3;
|
||||
time_t __unused4;
|
||||
};
|
||||
@@ -1,6 +1,3 @@
|
||||
#include <string.h>
|
||||
#include <bits/alltypes.h>
|
||||
|
||||
struct stat {
|
||||
dev_t st_dev;
|
||||
int __pad1[3];
|
||||
|
||||
@@ -330,6 +330,12 @@
|
||||
#define __NR_io_uring_setup 5425
|
||||
#define __NR_io_uring_enter 5426
|
||||
#define __NR_io_uring_register 5427
|
||||
#define __NR_open_tree 5428
|
||||
#define __NR_move_mount 5429
|
||||
#define __NR_fsopen 5430
|
||||
#define __NR_fsconfig 5431
|
||||
#define __NR_fsmount 5432
|
||||
#define __NR_fspick 5433
|
||||
|
||||
#define SYS_read 5000
|
||||
#define SYS_write 5001
|
||||
@@ -662,4 +668,10 @@
|
||||
#define SYS_pidfd_send_signal 5424
|
||||
#define SYS_io_uring_setup 5425
|
||||
#define SYS_io_uring_enter 5426
|
||||
#define SYS_io_uring_register 5427
|
||||
#define SYS_io_uring_register 5427
|
||||
#define SYS_open_tree 5428
|
||||
#define SYS_move_mount 5429
|
||||
#define SYS_fsopen 5430
|
||||
#define SYS_fsconfig 5431
|
||||
#define SYS_fsmount 5432
|
||||
#define SYS_fspick 5433
|
||||
@@ -14,11 +14,19 @@ typedef __builtin_va_list __isoc_va_list;
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
#ifdef __WCHAR_TYPE__
|
||||
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
|
||||
typedef __WCHAR_TYPE__ wchar_t;
|
||||
#define __DEFINED_wchar_t
|
||||
#endif
|
||||
|
||||
#else
|
||||
#if defined(__NEED_wchar_t) && !defined(__DEFINED_wchar_t)
|
||||
typedef long wchar_t;
|
||||
#define __DEFINED_wchar_t
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(__NEED_float_t) && !defined(__DEFINED_float_t)
|
||||
|
||||
@@ -9,6 +9,4 @@ struct ipc_perm {
|
||||
int __pad1;
|
||||
long long __pad2;
|
||||
long long __pad3;
|
||||
};
|
||||
|
||||
#define IPC_64 0x100
|
||||
};
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|
||||
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
#define LONG_BIT 64
|
||||
#define LONG_BIT 32
|
||||
#endif
|
||||
|
||||
#define LONG_MAX 0x7fffffffffffffffL
|
||||
#define LONG_MAX 0x7fffffffL
|
||||
#define LLONG_MAX 0x7fffffffffffffffLL
|
||||
@@ -0,0 +1,2 @@
|
||||
#define _POSIX_V6_ILP32_OFFBIG 1
|
||||
#define _POSIX_V7_ILP32_OFFBIG 1
|
||||
@@ -0,0 +1,3 @@
|
||||
#undef __WORDSIZE
|
||||
#define __WORDSIZE 32
|
||||
/* FIXME */
|
||||
@@ -407,6 +407,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_restart_syscall 0
|
||||
#define SYS_exit 1
|
||||
@@ -816,4 +822,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -1,10 +1,8 @@
|
||||
struct pt_regs {
|
||||
unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, mq;
|
||||
unsigned long trap, dar, dsisr, result;
|
||||
};
|
||||
|
||||
struct user {
|
||||
struct pt_regs regs;
|
||||
struct {
|
||||
unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, mq;
|
||||
unsigned long trap, dar, dsisr, result;
|
||||
} regs;
|
||||
unsigned long u_tsize, u_dsize, u_ssize;
|
||||
unsigned long start_code, start_data, start_stack;
|
||||
long signal;
|
||||
|
||||
@@ -9,6 +9,4 @@ struct ipc_perm {
|
||||
int __pad1;
|
||||
long long __pad2;
|
||||
long long __pad3;
|
||||
};
|
||||
|
||||
#define IPC_64 0x100
|
||||
};
|
||||
@@ -1,12 +0,0 @@
|
||||
struct msqid_ds {
|
||||
struct ipc_perm msg_perm;
|
||||
time_t msg_stime;
|
||||
time_t msg_rtime;
|
||||
time_t msg_ctime;
|
||||
unsigned long msg_cbytes;
|
||||
msgqnum_t msg_qnum;
|
||||
msglen_t msg_qbytes;
|
||||
pid_t msg_lspid;
|
||||
pid_t msg_lrpid;
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
#define _POSIX_V6_LP64_OFF64 1
|
||||
#define _POSIX_V7_LP64_OFF64 1
|
||||
@@ -1,13 +0,0 @@
|
||||
#include <endian.h>
|
||||
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t sem_ctime;
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
unsigned short __pad[3], sem_nsems;
|
||||
#else
|
||||
unsigned short sem_nsems, __pad[3];
|
||||
#endif
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -379,6 +379,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_restart_syscall 0
|
||||
#define SYS_exit 1
|
||||
@@ -760,4 +766,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -1,10 +1,8 @@
|
||||
struct pt_regs {
|
||||
unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;
|
||||
unsigned long trap, dar, dsisr, result;
|
||||
};
|
||||
|
||||
struct user {
|
||||
struct pt_regs regs;
|
||||
struct {
|
||||
unsigned long gpr[32], nip, msr, orig_gpr3, ctr, link, xer, ccr, softe;
|
||||
unsigned long trap, dar, dsisr, result;
|
||||
} regs;
|
||||
unsigned long u_tsize, u_dsize, u_ssize;
|
||||
unsigned long start_code, start_data, start_stack;
|
||||
long signal;
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
struct ipc_perm {
|
||||
key_t __ipc_perm_key;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uid_t cuid;
|
||||
gid_t cgid;
|
||||
mode_t mode;
|
||||
unsigned short __ipc_perm_seq;
|
||||
|
||||
unsigned long __pad1;
|
||||
unsigned long __pad2;
|
||||
};
|
||||
|
||||
#define IPC_64 0
|
||||
@@ -1,9 +0,0 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t sem_ctime;
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(time_t)-sizeof(short)];
|
||||
time_t __unused3;
|
||||
time_t __unused4;
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
#define SHMLBA 4096
|
||||
|
||||
struct shmid_ds
|
||||
{
|
||||
struct ipc_perm shm_perm;
|
||||
size_t shm_segsz;
|
||||
time_t shm_atime;
|
||||
time_t shm_dtime;
|
||||
time_t shm_ctime;
|
||||
pid_t shm_cpid;
|
||||
pid_t shm_lpid;
|
||||
unsigned long shm_nattch;
|
||||
unsigned long __pad1;
|
||||
unsigned long __pad2;
|
||||
};
|
||||
|
||||
struct shminfo {
|
||||
unsigned long shmmax, shmmin, shmmni, shmseg, shmall, __unused[4];
|
||||
};
|
||||
|
||||
struct shm_info {
|
||||
int __used_ids;
|
||||
unsigned long shm_tot, shm_rss, shm_swp;
|
||||
unsigned long __swap_attempts, __swap_successes;
|
||||
};
|
||||
@@ -6,46 +6,43 @@
|
||||
# define SIGSTKSZ 8192
|
||||
#endif
|
||||
|
||||
/* gregs[0] holds the program counter. */
|
||||
typedef unsigned long __riscv_mc_gp_state[32];
|
||||
|
||||
struct __riscv_mc_f_ext_state {
|
||||
unsigned int __f[32];
|
||||
unsigned int __fcsr;
|
||||
};
|
||||
|
||||
struct __riscv_mc_d_ext_state {
|
||||
unsigned long long __f[32];
|
||||
unsigned int __fcsr;
|
||||
};
|
||||
|
||||
struct __riscv_mc_q_ext_state {
|
||||
unsigned long long __f[64] __attribute__((aligned(16)));
|
||||
unsigned int __fcsr;
|
||||
unsigned int __reserved[3];
|
||||
};
|
||||
|
||||
union __riscv_mc_fp_state {
|
||||
struct __riscv_mc_f_ext_state __f;
|
||||
struct __riscv_mc_d_ext_state __d;
|
||||
struct __riscv_mc_q_ext_state __q;
|
||||
};
|
||||
|
||||
typedef struct mcontext_t {
|
||||
__riscv_mc_gp_state __gregs;
|
||||
union __riscv_mc_fp_state __fpregs;
|
||||
} mcontext_t;
|
||||
|
||||
#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
|
||||
typedef unsigned long greg_t;
|
||||
typedef unsigned long gregset_t[32];
|
||||
|
||||
struct __riscv_f_ext_state {
|
||||
unsigned int f[32];
|
||||
unsigned int fcsr;
|
||||
};
|
||||
|
||||
struct __riscv_d_ext_state {
|
||||
unsigned long long f[32];
|
||||
unsigned int fcsr;
|
||||
};
|
||||
|
||||
struct __riscv_q_ext_state {
|
||||
unsigned long long f[64] __attribute__((aligned(16)));
|
||||
unsigned int fcsr;
|
||||
unsigned int reserved[3];
|
||||
};
|
||||
|
||||
union __riscv_fp_state {
|
||||
struct __riscv_f_ext_state f;
|
||||
struct __riscv_d_ext_state d;
|
||||
struct __riscv_q_ext_state q;
|
||||
};
|
||||
|
||||
typedef union __riscv_fp_state fpregset_t;
|
||||
|
||||
typedef struct sigcontext {
|
||||
typedef union __riscv_mc_fp_state fpregset_t;
|
||||
struct sigcontext {
|
||||
gregset_t gregs;
|
||||
fpregset_t fpregs;
|
||||
} mcontext_t;
|
||||
|
||||
#else
|
||||
typedef struct {
|
||||
unsigned long gregs[32];
|
||||
unsigned long long fpregs[66];
|
||||
} mcontext_t;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct sigaltstack {
|
||||
@@ -54,10 +51,10 @@ struct sigaltstack {
|
||||
size_t ss_size;
|
||||
};
|
||||
|
||||
typedef struct __ucontext
|
||||
typedef struct ucontext_t
|
||||
{
|
||||
unsigned long uc_flags;
|
||||
struct __ucontext *uc_link;
|
||||
struct ucontext_t *uc_link;
|
||||
stack_t uc_stack;
|
||||
sigset_t uc_sigmask;
|
||||
mcontext_t uc_mcontext;
|
||||
|
||||
@@ -273,6 +273,21 @@
|
||||
#define __NR_pkey_mprotect 288
|
||||
#define __NR_pkey_alloc 289
|
||||
#define __NR_pkey_free 290
|
||||
#define __NR_statx 291
|
||||
#define __NR_io_pgetevents 292
|
||||
#define __NR_rseq 293
|
||||
#define __NR_kexec_file_load 294
|
||||
#define __NR_pidfd_send_signal 424
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define __NR_sysriscv __NR_arch_specific_syscall
|
||||
#define __NR_riscv_flush_icache (__NR_sysriscv + 15)
|
||||
#define SYS_io_setup 0
|
||||
@@ -550,5 +565,19 @@
|
||||
#define SYS_pkey_mprotect 288
|
||||
#define SYS_pkey_alloc 289
|
||||
#define SYS_pkey_free 290
|
||||
#define SYS_statx 291
|
||||
#define SYS_io_pgetevents 292
|
||||
#define SYS_rseq 293
|
||||
#define SYS_kexec_file_load 294
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
#define SYS_sysriscv __NR_arch_specific_syscall
|
||||
#define SYS_riscv_flush_icache (__NR_sysriscv + 15)
|
||||
@@ -1,43 +1,5 @@
|
||||
struct user_regs_struct {
|
||||
unsigned long pc;
|
||||
unsigned long ra;
|
||||
unsigned long sp;
|
||||
unsigned long gp;
|
||||
unsigned long tp;
|
||||
unsigned long t0;
|
||||
unsigned long t1;
|
||||
unsigned long t2;
|
||||
unsigned long s0;
|
||||
unsigned long s1;
|
||||
unsigned long a0;
|
||||
unsigned long a1;
|
||||
unsigned long a2;
|
||||
unsigned long a3;
|
||||
unsigned long a4;
|
||||
unsigned long a5;
|
||||
unsigned long a6;
|
||||
unsigned long a7;
|
||||
unsigned long s2;
|
||||
unsigned long s3;
|
||||
unsigned long s4;
|
||||
unsigned long s5;
|
||||
unsigned long s6;
|
||||
unsigned long s7;
|
||||
unsigned long s8;
|
||||
unsigned long s9;
|
||||
unsigned long s10;
|
||||
unsigned long s11;
|
||||
unsigned long t3;
|
||||
unsigned long t4;
|
||||
unsigned long t5;
|
||||
unsigned long t6;
|
||||
};
|
||||
|
||||
struct user_fpregs_struct {
|
||||
double f[32];
|
||||
unsigned int fcsr;
|
||||
};
|
||||
#include <signal.h>
|
||||
|
||||
#define ELF_NGREG 32
|
||||
typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NGREG];
|
||||
typedef struct user_fpregs_struct elf_fpregset_t;
|
||||
typedef union __riscv_mc_fp_state elf_fpregset_t;
|
||||
@@ -1,14 +0,0 @@
|
||||
struct ipc_perm {
|
||||
key_t __ipc_perm_key;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uid_t cuid;
|
||||
gid_t cgid;
|
||||
mode_t mode;
|
||||
unsigned short __pad1;
|
||||
unsigned short __ipc_perm_seq;
|
||||
unsigned long __pad2;
|
||||
unsigned long __pad3;
|
||||
};
|
||||
|
||||
#define IPC_64 0x100
|
||||
@@ -1,12 +0,0 @@
|
||||
struct msqid_ds {
|
||||
struct ipc_perm msg_perm;
|
||||
time_t msg_stime;
|
||||
time_t msg_rtime;
|
||||
time_t msg_ctime;
|
||||
unsigned long msg_cbytes;
|
||||
msgqnum_t msg_qnum;
|
||||
msglen_t msg_qbytes;
|
||||
pid_t msg_lspid;
|
||||
pid_t msg_lrpid;
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
#define _POSIX_V6_LP64_OFF64 1
|
||||
#define _POSIX_V7_LP64_OFF64 1
|
||||
@@ -1,2 +0,0 @@
|
||||
#undef __WORDSIZE
|
||||
#define __WORDSIZE 64
|
||||
@@ -1,7 +0,0 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
time_t sem_ctime;
|
||||
unsigned short __pad[3], sem_nsems;
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -344,6 +344,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_exit 1
|
||||
#define SYS_fork 2
|
||||
@@ -690,4 +696,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -1,13 +0,0 @@
|
||||
struct ipc_perm {
|
||||
key_t __ipc_perm_key;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uid_t cuid;
|
||||
gid_t cgid;
|
||||
mode_t mode;
|
||||
int __ipc_perm_seq;
|
||||
long __pad1;
|
||||
long __pad2;
|
||||
};
|
||||
|
||||
#define IPC_64 0
|
||||
@@ -1,12 +0,0 @@
|
||||
struct msqid_ds {
|
||||
struct ipc_perm msg_perm;
|
||||
time_t msg_stime;
|
||||
time_t msg_rtime;
|
||||
time_t msg_ctime;
|
||||
unsigned long msg_cbytes;
|
||||
msgqnum_t msg_qnum;
|
||||
msglen_t msg_qbytes;
|
||||
pid_t msg_lspid;
|
||||
pid_t msg_lrpid;
|
||||
unsigned long __unused[2];
|
||||
};
|
||||
@@ -1,2 +0,0 @@
|
||||
#define _POSIX_V6_LP64_OFF64 1
|
||||
#define _POSIX_V7_LP64_OFF64 1
|
||||
@@ -0,0 +1,11 @@
|
||||
struct semid_ds {
|
||||
struct ipc_perm sem_perm;
|
||||
time_t sem_otime;
|
||||
long __unused1;
|
||||
time_t sem_ctime;
|
||||
long __unused2;
|
||||
unsigned short sem_nsems;
|
||||
char __sem_nsems_pad[sizeof(long)-sizeof(short)];
|
||||
long __unused3;
|
||||
long __unused4;
|
||||
};
|
||||
@@ -337,6 +337,12 @@
|
||||
#define __NR_io_uring_setup 425
|
||||
#define __NR_io_uring_enter 426
|
||||
#define __NR_io_uring_register 427
|
||||
#define __NR_open_tree 428
|
||||
#define __NR_move_mount 429
|
||||
#define __NR_fsopen 430
|
||||
#define __NR_fsconfig 431
|
||||
#define __NR_fsmount 432
|
||||
#define __NR_fspick 433
|
||||
|
||||
#define SYS_read 0
|
||||
#define SYS_write 1
|
||||
@@ -676,4 +682,10 @@
|
||||
#define SYS_pidfd_send_signal 424
|
||||
#define SYS_io_uring_setup 425
|
||||
#define SYS_io_uring_enter 426
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_io_uring_register 427
|
||||
#define SYS_open_tree 428
|
||||
#define SYS_move_mount 429
|
||||
#define SYS_fsopen 430
|
||||
#define SYS_fsconfig 431
|
||||
#define SYS_fsmount 432
|
||||
#define SYS_fspick 433
|
||||
@@ -0,0 +1,43 @@
|
||||
With exception of certain parts that are prominently marked as being
|
||||
in the Public Domain, BSD, or LGPL this Software is provided under the
|
||||
Zope Public License (ZPL) Version 2.1.
|
||||
|
||||
Copyright (c) 2009 - 2013 by the mingw-w64 project
|
||||
|
||||
See the AUTHORS file for the list of contributors to the mingw-w64 project.
|
||||
|
||||
This license has been certified as open source. It has also been designated
|
||||
as GPL compatible by the Free Software Foundation (FSF).
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions in source code must retain the accompanying copyright
|
||||
notice, this list of conditions, and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the accompanying
|
||||
copyright notice, this list of conditions, and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
3. Names of the copyright holders must not be used to endorse or promote
|
||||
products derived from this software without prior written permission
|
||||
from the copyright holders.
|
||||
4. The right to distribute this software or to use it for any purpose does
|
||||
not give you the right to use Servicemarks (sm) or Trademarks (tm) of
|
||||
the copyright holders. Use of them is covered by separate agreement
|
||||
with the copyright holders.
|
||||
5. If any files are modified, you must cause the modified files to carry
|
||||
prominent notices stating that you changed the files and the date of
|
||||
any change.
|
||||
|
||||
Disclaimer
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
|
||||
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||||
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -0,0 +1,65 @@
|
||||
LIBRARY "bcrypt.dll"
|
||||
EXPORTS
|
||||
BCryptAddContextFunction
|
||||
BCryptAddContextFunctionProvider
|
||||
BCryptCloseAlgorithmProvider
|
||||
BCryptConfigureContext
|
||||
BCryptConfigureContextFunction
|
||||
BCryptCreateContext
|
||||
BCryptCreateHash
|
||||
BCryptCreateMultiHash
|
||||
BCryptDecrypt
|
||||
BCryptDeleteContext
|
||||
BCryptDeriveKey
|
||||
BCryptDeriveKeyCapi
|
||||
BCryptDeriveKeyPBKDF2
|
||||
BCryptDestroyHash
|
||||
BCryptDestroyKey
|
||||
BCryptDestroySecret
|
||||
BCryptDuplicateHash
|
||||
BCryptDuplicateKey
|
||||
BCryptEncrypt
|
||||
BCryptEnumAlgorithms
|
||||
BCryptEnumContextFunctionProviders
|
||||
BCryptEnumContextFunctions
|
||||
BCryptEnumContexts
|
||||
BCryptEnumProviders
|
||||
BCryptEnumRegisteredProviders
|
||||
BCryptExportKey
|
||||
BCryptFinalizeKeyPair
|
||||
BCryptFinishHash
|
||||
BCryptFreeBuffer
|
||||
BCryptGenRandom
|
||||
BCryptGenerateKeyPair
|
||||
BCryptGenerateSymmetricKey
|
||||
BCryptGetFipsAlgorithmMode
|
||||
BCryptGetProperty
|
||||
BCryptHashData
|
||||
BCryptImportKey
|
||||
BCryptImportKeyPair
|
||||
BCryptKeyDerivation
|
||||
BCryptOpenAlgorithmProvider
|
||||
BCryptProcessMultiOperations
|
||||
BCryptQueryContextConfiguration
|
||||
BCryptQueryContextFunctionConfiguration
|
||||
BCryptQueryContextFunctionProperty
|
||||
BCryptQueryProviderRegistration
|
||||
BCryptRegisterConfigChangeNotify
|
||||
BCryptRegisterProvider
|
||||
BCryptRemoveContextFunction
|
||||
BCryptRemoveContextFunctionProvider
|
||||
BCryptResolveProviders
|
||||
BCryptSecretAgreement
|
||||
BCryptSetAuditingInterface
|
||||
BCryptSetContextFunctionProperty
|
||||
BCryptSetProperty
|
||||
BCryptSignHash
|
||||
BCryptUnregisterConfigChangeNotify
|
||||
BCryptUnregisterProvider
|
||||
BCryptVerifySignature
|
||||
GetAsymmetricEncryptionInterface
|
||||
GetCipherInterface
|
||||
GetHashInterface
|
||||
GetRngInterface
|
||||
GetSecretAgreementInterface
|
||||
GetSignatureInterface
|
||||
@@ -0,0 +1,125 @@
|
||||
LIBRARY COMCTL32.dll
|
||||
EXPORTS
|
||||
MenuHelp
|
||||
ShowHideMenuCtl
|
||||
GetEffectiveClientRect
|
||||
DrawStatusTextA
|
||||
CreateStatusWindowA
|
||||
CreateToolbar
|
||||
CreateMappedBitmap
|
||||
DPA_LoadStream
|
||||
DPA_SaveStream
|
||||
DPA_Merge
|
||||
CreatePropertySheetPage
|
||||
MakeDragList
|
||||
LBItemFromPt
|
||||
DrawInsert
|
||||
CreateUpDownControl
|
||||
InitCommonControls
|
||||
CreatePropertySheetPageA
|
||||
CreatePropertySheetPageW
|
||||
CreateStatusWindow
|
||||
CreateStatusWindowW
|
||||
CreateToolbarEx
|
||||
DestroyPropertySheetPage
|
||||
DllGetVersion
|
||||
DllInstall
|
||||
DrawStatusText
|
||||
DrawStatusTextW
|
||||
FlatSB_EnableScrollBar
|
||||
FlatSB_GetScrollInfo
|
||||
FlatSB_GetScrollPos
|
||||
FlatSB_GetScrollProp
|
||||
FlatSB_GetScrollPropPtr
|
||||
FlatSB_GetScrollRange
|
||||
FlatSB_SetScrollInfo
|
||||
FlatSB_SetScrollPos
|
||||
FlatSB_SetScrollProp
|
||||
FlatSB_SetScrollRange
|
||||
FlatSB_ShowScrollBar
|
||||
GetMUILanguage
|
||||
ImageList_Add
|
||||
ImageList_AddIcon
|
||||
ImageList_AddMasked
|
||||
ImageList_BeginDrag
|
||||
ImageList_Copy
|
||||
ImageList_Create
|
||||
ImageList_Destroy
|
||||
ImageList_DragEnter
|
||||
ImageList_DragLeave
|
||||
ImageList_DragMove
|
||||
ImageList_DragShowNolock
|
||||
ImageList_Draw
|
||||
ImageList_DrawEx
|
||||
ImageList_DrawIndirect
|
||||
ImageList_Duplicate
|
||||
ImageList_EndDrag
|
||||
ImageList_GetBkColor
|
||||
ImageList_GetDragImage
|
||||
ImageList_GetFlags
|
||||
ImageList_GetIcon
|
||||
ImageList_GetIconSize
|
||||
ImageList_GetImageCount
|
||||
ImageList_GetImageInfo
|
||||
ImageList_GetImageRect
|
||||
ImageList_LoadImage
|
||||
ImageList_LoadImageA
|
||||
ImageList_LoadImageW
|
||||
ImageList_Merge
|
||||
ImageList_Read
|
||||
ImageList_Remove
|
||||
ImageList_Replace
|
||||
ImageList_ReplaceIcon
|
||||
ImageList_SetBkColor
|
||||
ImageList_SetDragCursorImage
|
||||
ImageList_SetFilter
|
||||
ImageList_SetFlags
|
||||
ImageList_SetIconSize
|
||||
ImageList_SetImageCount
|
||||
ImageList_SetOverlayImage
|
||||
ImageList_Write
|
||||
InitCommonControlsEx
|
||||
InitMUILanguage
|
||||
InitializeFlatSB
|
||||
LoadIconMetric
|
||||
PropertySheet
|
||||
PropertySheetA
|
||||
PropertySheetW
|
||||
RegisterClassNameW
|
||||
UninitializeFlatSB
|
||||
_TrackMouseEvent
|
||||
FreeMRUList
|
||||
Str_SetPtrW
|
||||
DSA_Create
|
||||
DSA_Destroy
|
||||
DSA_GetItem
|
||||
DSA_GetItemPtr
|
||||
DSA_InsertItem
|
||||
DSA_SetItem
|
||||
DSA_DeleteItem
|
||||
DSA_DeleteAllItems
|
||||
DPA_Create
|
||||
DPA_Destroy
|
||||
DPA_Grow
|
||||
DPA_Clone
|
||||
DPA_GetPtr
|
||||
DPA_GetPtrIndex
|
||||
DPA_InsertPtr
|
||||
DPA_SetPtr
|
||||
DPA_DeletePtr
|
||||
DPA_DeleteAllPtrs
|
||||
DPA_Sort
|
||||
DPA_Search
|
||||
DPA_CreateEx
|
||||
DPA_EnumCallback
|
||||
DPA_DestroyCallback
|
||||
DSA_EnumCallback
|
||||
DSA_DestroyCallback
|
||||
CreateMRUListW
|
||||
AddMRUStringW
|
||||
EnumMRUListW
|
||||
SetWindowSubclass
|
||||
RemoveWindowSubclass
|
||||
DefSubclassProc
|
||||
TaskDialog
|
||||
TaskDialogIndirect
|
||||
@@ -0,0 +1,34 @@
|
||||
;
|
||||
; Exports of file comdlg32.dll
|
||||
;
|
||||
; Autogenerated by gen_exportdef
|
||||
; Written by Kai Tietz, 2007
|
||||
;
|
||||
LIBRARY comdlg32.dll
|
||||
EXPORTS
|
||||
ChooseColorA
|
||||
ChooseColorW
|
||||
ChooseFontA
|
||||
ChooseFontW
|
||||
CommDlgExtendedError
|
||||
FindTextA
|
||||
FindTextW
|
||||
GetFileTitleA
|
||||
GetFileTitleW
|
||||
GetOpenFileNameA
|
||||
GetOpenFileNameW
|
||||
GetSaveFileNameA
|
||||
GetSaveFileNameW
|
||||
LoadAlterBitmap
|
||||
PageSetupDlgA
|
||||
PageSetupDlgW
|
||||
PrintDlgA
|
||||
PrintDlgExA
|
||||
PrintDlgExW
|
||||
PrintDlgW
|
||||
ReplaceTextA
|
||||
ReplaceTextW
|
||||
Ssync_ANSI_UNICODE_Struct_For_WOW
|
||||
WantArrows
|
||||
dwLBSubclass
|
||||
dwOKSubclass
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user