mirror of
https://github.com/janet-lang/janet
synced 2025-11-17 15:57:12 +00:00
Compare commits
1 Commits
undo-deep-
...
ev-reduce-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7c5e75343 |
@@ -19,8 +19,3 @@ tasks:
|
|||||||
ninja
|
ninja
|
||||||
ninja test
|
ninja test
|
||||||
sudo ninja install
|
sudo ninja install
|
||||||
- meson_min: |
|
|
||||||
cd janet
|
|
||||||
meson setup build_meson_min --buildtype=release -Dsingle_threaded=true -Dnanbox=false -Ddynamic_modules=false -Ddocstrings=false -Dnet=false -Dsourcemaps=false -Dpeg=false -Dassembler=false -Dint_types=false -Dreduced_os=true -Dffi=false
|
|
||||||
cd build_meson_min
|
|
||||||
ninja
|
|
||||||
|
|||||||
31
.github/workflows/release.yml
vendored
31
.github/workflows/release.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest, macos-13 ]
|
os: [ ubuntu-latest, macos-latest ]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
@@ -39,35 +39,6 @@ jobs:
|
|||||||
build/c/janet.c
|
build/c/janet.c
|
||||||
build/c/shell.c
|
build/c/shell.c
|
||||||
|
|
||||||
release-arm:
|
|
||||||
permissions:
|
|
||||||
contents: write # for softprops/action-gh-release to create GitHub release
|
|
||||||
name: Build release binaries
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ macos-latest ]
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@master
|
|
||||||
- name: Set the version
|
|
||||||
run: echo "version=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
|
|
||||||
- name: Set the platform
|
|
||||||
run: echo "platform=$(tr '[A-Z]' '[a-z]' <<< $RUNNER_OS)" >> $GITHUB_ENV
|
|
||||||
- name: Compile the project
|
|
||||||
run: make clean && make
|
|
||||||
- name: Build the artifact
|
|
||||||
run: JANET_DIST_DIR=janet-${{ env.version }}-${{ env.platform }} make build/janet-${{ env.version }}-${{ env.platform }}-aarch64.tar.gz
|
|
||||||
- name: Draft the release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
with:
|
|
||||||
draft: true
|
|
||||||
files: |
|
|
||||||
build/*.gz
|
|
||||||
build/janet.h
|
|
||||||
build/c/janet.c
|
|
||||||
build/c/shell.c
|
|
||||||
|
|
||||||
release-windows:
|
release-windows:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write # for softprops/action-gh-release to create GitHub release
|
contents: write # for softprops/action-gh-release to create GitHub release
|
||||||
|
|||||||
59
.github/workflows/test.yml
vendored
59
.github/workflows/test.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ ubuntu-latest, macos-latest, macos-13 ]
|
os: [ ubuntu-latest, macos-latest ]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
@@ -23,10 +23,7 @@ jobs:
|
|||||||
|
|
||||||
test-windows:
|
test-windows:
|
||||||
name: Build and test on Windows
|
name: Build and test on Windows
|
||||||
strategy:
|
runs-on: windows-latest
|
||||||
matrix:
|
|
||||||
os: [ windows-latest, windows-2019 ]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
@@ -38,61 +35,28 @@ jobs:
|
|||||||
- name: Test the project
|
- name: Test the project
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: build_win test
|
run: build_win test
|
||||||
- name: Test installer build
|
|
||||||
shell: cmd
|
|
||||||
run: build_win dist
|
|
||||||
|
|
||||||
test-windows-min:
|
|
||||||
name: Build and test on Windows Minimal build
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
os: [ windows-2019 ]
|
|
||||||
runs-on: ${{ matrix.os }}
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@master
|
|
||||||
- name: Setup MSVC
|
|
||||||
uses: ilammy/msvc-dev-cmd@v1
|
|
||||||
- name: Setup Python
|
|
||||||
uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: '3.x'
|
|
||||||
- name: Install Python Dependencies
|
|
||||||
run: pip install meson ninja
|
|
||||||
- name: Build
|
|
||||||
shell: cmd
|
|
||||||
run: |
|
|
||||||
meson setup build_meson_min --buildtype=release -Dsingle_threaded=true -Dnanbox=false -Ddynamic_modules=false -Ddocstrings=false -Dnet=false -Dsourcemaps=false -Dpeg=false -Dassembler=false -Dint_types=false -Dreduced_os=true -Dffi=false
|
|
||||||
cd build_meson_min
|
|
||||||
ninja
|
|
||||||
|
|
||||||
test-mingw:
|
test-mingw:
|
||||||
name: Build on Windows with Mingw
|
name: Build on Windows with Mingw (no test yet)
|
||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
shell: msys2 {0}
|
shell: msys2 {0}
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
msystem: [ UCRT64, CLANG64 ]
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout the repository
|
- name: Checkout the repository
|
||||||
uses: actions/checkout@master
|
uses: actions/checkout@master
|
||||||
- name: Setup Mingw
|
- name: Setup Mingw
|
||||||
uses: msys2/setup-msys2@v2
|
uses: msys2/setup-msys2@v2
|
||||||
with:
|
with:
|
||||||
msystem: ${{ matrix.msystem }}
|
msystem: UCRT64
|
||||||
update: true
|
update: true
|
||||||
install: >-
|
install: >-
|
||||||
base-devel
|
base-devel
|
||||||
git
|
git
|
||||||
gcc
|
gcc
|
||||||
- name: Build
|
- name: Build the project
|
||||||
shell: cmd
|
shell: cmd
|
||||||
run: make -j4 CC=gcc
|
run: make -j4 CC=gcc JANET_NO_AMALG=1
|
||||||
- name: Test
|
|
||||||
shell: cmd
|
|
||||||
run: make -j4 CC=gcc test
|
|
||||||
|
|
||||||
test-mingw-linux:
|
test-mingw-linux:
|
||||||
name: Build and test with Mingw on Linux + Wine
|
name: Build and test with Mingw on Linux + Wine
|
||||||
@@ -125,14 +89,3 @@ jobs:
|
|||||||
run: make RUN="qemu-arm -L /usr/arm-linux-gnueabi/" CC=arm-linux-gnueabi-gcc LD=arm-linux-gnueabi-gcc
|
run: make RUN="qemu-arm -L /usr/arm-linux-gnueabi/" CC=arm-linux-gnueabi-gcc LD=arm-linux-gnueabi-gcc
|
||||||
- name: Test the project
|
- name: Test the project
|
||||||
run: make RUN="qemu-arm -L /usr/arm-linux-gnueabi/" SUBRUN="qemu-arm -L /usr/arm-linux-gnueabi/" test VERBOSE=1
|
run: make RUN="qemu-arm -L /usr/arm-linux-gnueabi/" SUBRUN="qemu-arm -L /usr/arm-linux-gnueabi/" test VERBOSE=1
|
||||||
|
|
||||||
test-s390x-linux:
|
|
||||||
name: Build and test s390x in qemu
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout the repository
|
|
||||||
uses: actions/checkout@master
|
|
||||||
- name: Do Qemu build and test
|
|
||||||
run: |
|
|
||||||
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
|
|
||||||
docker run --rm -v .:/janet --platform linux/s390x ubuntu bash -c "apt-get -y update && apt-get -y install git build-essential && cd /janet && make -j3 && make test"
|
|
||||||
|
|||||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,42 +1,18 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## ??? - Unreleased
|
## Unreleased - ???
|
||||||
- Add `struct/rawget` to get values from a struct without a prototype.
|
|
||||||
- Fix `deep=` and `deep-not=` to better handle degenerate cases with mutable table keys. Keys are now compared by value rather than
|
|
||||||
structure to avoid degenerate cases.
|
|
||||||
- Long strings will now dedent on `\r\n` instead of just `\n`.
|
|
||||||
- Add `ev/to-file` for synchronous resource operations
|
|
||||||
|
|
||||||
## 1.37.1 - 2024-12-05
|
|
||||||
- Fix meson cross compilation
|
|
||||||
- Update timeout documentation for networking APIs: timeouts raise errors and do not return nil.
|
|
||||||
- Add `janet_addtimeout_nil(double sec);` to the C API.
|
|
||||||
- Change string hashing.
|
|
||||||
- Fix string equality bug.
|
|
||||||
- Add `assertf`
|
|
||||||
- Change how JANET_PROFILE is loaded to allow more easily customizing the environment.
|
|
||||||
- Add `*repl-prompt*` dynamic binding to allow customizing the built in repl.
|
|
||||||
- Add multiple path support in the `JANET_PATH` environment variables. This lets
|
|
||||||
user more easily import modules from many directories.
|
|
||||||
- Add `nth` and `only-tags` PEG specials to select from sub-captures while
|
|
||||||
dropping the rest.
|
|
||||||
|
|
||||||
## 1.36.0 - 2024-09-07
|
|
||||||
- Improve error messages in `bundle/add*` functions.
|
|
||||||
- Add CI testing and verify tests pass on the s390x architecture.
|
|
||||||
- Save `:source-form` in environment entries when `*debug*` is set.
|
- Save `:source-form` in environment entries when `*debug*` is set.
|
||||||
- Add experimental `filewatch/` module for listening to file system changes on Linux and Windows.
|
- Add experimental `filewatch/` module for listening to file system changes.
|
||||||
- Add `bundle/who-is` to query which bundle a file on disk was installed by.
|
- Add `bundle/who-is` to query which bundle a file on disk was installed by.
|
||||||
- Add `geomean` function
|
- Add `geomean` function
|
||||||
- Add `:R` and `:W` flags to `os/pipe` to create blocking pipes on Posix and Windows systems.
|
- Add `:R` and `:W` flags to `os/pipe` to create blocking pipes on Posix and Windows systems.
|
||||||
These streams cannot be directly read to and written from, but can be passed to subprocesses.
|
These streams cannot be directly read to and written from, but can be passed to subprocesses.
|
||||||
- Add `array/join`
|
- Add `array/join`
|
||||||
- Add `tuple/join`
|
- Add `tuple/join`
|
||||||
- Add `bundle/add-bin` to make installing scripts easier. This also establishes a packaging convention for it.
|
|
||||||
- Fix marshalling weak tables and weak arrays.
|
- Fix marshalling weak tables and weak arrays.
|
||||||
- Fix bug in `ev/` module that could accidentally close sockets on accident.
|
|
||||||
- Expose C functions for constructing weak tables in janet.h
|
- Expose C functions for constructing weak tables in janet.h
|
||||||
|
- Add `bundle/add-bin` to make installing scripts easier. This also establishes a packaging convention for it.
|
||||||
- Let range take non-integer values.
|
- Let range take non-integer values.
|
||||||
|
|
||||||
## 1.35.2 - 2024-06-16
|
## 1.35.2 - 2024-06-16
|
||||||
|
|||||||
13
Makefile
13
Makefile
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2024 Calvin Rose
|
# Copyright (c) 2023 Calvin Rose
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
@@ -43,7 +43,6 @@ JANET_DIST_DIR?=janet-dist
|
|||||||
JANET_BOOT_FLAGS:=. JANET_PATH '$(JANET_PATH)'
|
JANET_BOOT_FLAGS:=. JANET_PATH '$(JANET_PATH)'
|
||||||
JANET_TARGET_OBJECTS=build/janet.o build/shell.o
|
JANET_TARGET_OBJECTS=build/janet.o build/shell.o
|
||||||
JPM_TAG?=master
|
JPM_TAG?=master
|
||||||
SPORK_TAG?=master
|
|
||||||
HAS_SHARED?=1
|
HAS_SHARED?=1
|
||||||
DEBUGGER=gdb
|
DEBUGGER=gdb
|
||||||
SONAME_SETTER=-Wl,-soname,
|
SONAME_SETTER=-Wl,-soname,
|
||||||
@@ -206,9 +205,9 @@ build/%.bin.o: src/%.c $(JANET_HEADERS) $(JANET_LOCAL_HEADERS) Makefile
|
|||||||
########################
|
########################
|
||||||
|
|
||||||
ifeq ($(UNAME), Darwin)
|
ifeq ($(UNAME), Darwin)
|
||||||
SONAME=libjanet.1.37.dylib
|
SONAME=libjanet.1.35.dylib
|
||||||
else
|
else
|
||||||
SONAME=libjanet.so.1.37
|
SONAME=libjanet.so.1.35
|
||||||
endif
|
endif
|
||||||
|
|
||||||
build/c/shell.c: src/mainclient/shell.c
|
build/c/shell.c: src/mainclient/shell.c
|
||||||
@@ -360,12 +359,6 @@ install-jpm-git: $(JANET_TARGET)
|
|||||||
JANET_LIBPATH='$(LIBDIR)' \
|
JANET_LIBPATH='$(LIBDIR)' \
|
||||||
$(RUN) ../../$(JANET_TARGET) ./bootstrap.janet
|
$(RUN) ../../$(JANET_TARGET) ./bootstrap.janet
|
||||||
|
|
||||||
install-spork-git: $(JANET_TARGET)
|
|
||||||
mkdir -p build
|
|
||||||
rm -rf build/spork
|
|
||||||
git clone --depth=1 --branch='$(SPORK_TAG)' https://github.com/janet-lang/spork.git build/spork
|
|
||||||
$(JANET_TARGET) -e '(bundle/install "build/spork")'
|
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
-rm '$(DESTDIR)$(BINDIR)/janet'
|
-rm '$(DESTDIR)$(BINDIR)/janet'
|
||||||
-rm -rf '$(DESTDIR)$(INCLUDEDIR)/janet'
|
-rm -rf '$(DESTDIR)$(INCLUDEDIR)/janet'
|
||||||
|
|||||||
11
README.md
11
README.md
@@ -1,4 +1,4 @@
|
|||||||
[](https://janet.zulipchat.com)
|
[](https://gitter.im/janet-language/community)
|
||||||
|
|
||||||
[](https://builds.sr.ht/~bakpakin/janet/commits/master/freebsd.yml?)
|
[](https://builds.sr.ht/~bakpakin/janet/commits/master/freebsd.yml?)
|
||||||
[](https://builds.sr.ht/~bakpakin/janet/commits/master/openbsd.yml?)
|
[](https://builds.sr.ht/~bakpakin/janet/commits/master/openbsd.yml?)
|
||||||
@@ -18,6 +18,9 @@ to run script files. This client program is separate from the core runtime, so
|
|||||||
Janet can be embedded in other programs. Try Janet in your browser at
|
Janet can be embedded in other programs. Try Janet in your browser at
|
||||||
<https://janet-lang.org>.
|
<https://janet-lang.org>.
|
||||||
|
|
||||||
|
If you'd like to financially support the ongoing development of Janet, consider
|
||||||
|
[sponsoring its primary author](https://github.com/sponsors/bakpakin) through GitHub.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
@@ -250,10 +253,8 @@ Emacs, and Atom each have syntax packages for the Janet language, though.
|
|||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
If you just want to try out the language, you don't need to install anything.
|
See the [Introduction](https://janet-lang.org/docs/index.html) for more details. If you just want
|
||||||
In this case you can also move the `janet` executable wherever you want on
|
to try out the language, you don't need to install anything. You can also move the `janet` executable wherever you want on your system and run it.
|
||||||
your system and run it. However, for a fuller setup, please see the
|
|
||||||
[Introduction](https://janet-lang.org/docs/index.html) for more details.
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
|||||||
@@ -121,6 +121,7 @@ copy README.md dist\README.md
|
|||||||
|
|
||||||
copy janet.lib dist\janet.lib
|
copy janet.lib dist\janet.lib
|
||||||
copy janet.exp dist\janet.exp
|
copy janet.exp dist\janet.exp
|
||||||
|
copy janet.def dist\janet.def
|
||||||
|
|
||||||
janet.exe tools\patch-header.janet src\include\janet.h src\conf\janetconf.h build\janet.h
|
janet.exe tools\patch-header.janet src\include\janet.h src\conf\janetconf.h build\janet.h
|
||||||
copy build\janet.h dist\janet.h
|
copy build\janet.h dist\janet.h
|
||||||
@@ -138,8 +139,7 @@ if defined APPVEYOR_REPO_TAG_NAME (
|
|||||||
set RELEASE_VERSION=%JANET_VERSION%
|
set RELEASE_VERSION=%JANET_VERSION%
|
||||||
)
|
)
|
||||||
if defined CI (
|
if defined CI (
|
||||||
set WIXBIN="%WIX%bin\"
|
set WIXBIN="c:\Program Files (x86)\WiX Toolset v3.11\bin\"
|
||||||
echo WIXBIN = %WIXBIN%
|
|
||||||
) else (
|
) else (
|
||||||
set WIXBIN=
|
set WIXBIN=
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
(def abc 123)
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
(defn install
|
|
||||||
[manifest &]
|
|
||||||
(bundle/add-file manifest "badmod.janet"))
|
|
||||||
|
|
||||||
(defn check
|
|
||||||
[&]
|
|
||||||
(error "Check failed!"))
|
|
||||||
3
janet.1
3
janet.1
@@ -255,8 +255,7 @@ and then arguments to the script.
|
|||||||
.RS
|
.RS
|
||||||
The location to look for Janet libraries. This is the only environment variable Janet needs to
|
The location to look for Janet libraries. This is the only environment variable Janet needs to
|
||||||
find native and source code modules. If no JANET_PATH is set, Janet will look in
|
find native and source code modules. If no JANET_PATH is set, Janet will look in
|
||||||
the default location set at compile time. This should be a list of as well as a colon
|
the default location set at compile time.
|
||||||
separate list of such directories.
|
|
||||||
.RE
|
.RE
|
||||||
|
|
||||||
.B JANET_PROFILE
|
.B JANET_PROFILE
|
||||||
|
|||||||
31
meson.build
31
meson.build
@@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2024 Calvin Rose and contributors
|
# Copyright (c) 2023 Calvin Rose and contributors
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to
|
# of this software and associated documentation files (the "Software"), to
|
||||||
@@ -20,23 +20,14 @@
|
|||||||
|
|
||||||
project('janet', 'c',
|
project('janet', 'c',
|
||||||
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
default_options : ['c_std=c99', 'build.c_std=c99', 'b_lundef=false', 'default_library=both'],
|
||||||
version : '1.37.1')
|
version : '1.35.2')
|
||||||
|
|
||||||
# Global settings
|
# Global settings
|
||||||
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
janet_path = join_paths(get_option('prefix'), get_option('libdir'), 'janet')
|
||||||
header_path = join_paths(get_option('prefix'), get_option('includedir'), 'janet')
|
header_path = join_paths(get_option('prefix'), get_option('includedir'), 'janet')
|
||||||
|
|
||||||
# Compilers
|
# Link math library on all systems
|
||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
native_cc = meson.get_compiler('c', native : true)
|
|
||||||
|
|
||||||
# Native deps
|
|
||||||
native_m_dep = native_cc.find_library('m', required : false)
|
|
||||||
native_dl_dep = native_cc.find_library('dl', required : false)
|
|
||||||
native_android_spawn_dep = native_cc.find_library('android-spawn', required : false)
|
|
||||||
native_thread_dep = dependency('threads', native : true)
|
|
||||||
|
|
||||||
# Deps
|
|
||||||
m_dep = cc.find_library('m', required : false)
|
m_dep = cc.find_library('m', required : false)
|
||||||
dl_dep = cc.find_library('dl', required : false)
|
dl_dep = cc.find_library('dl', required : false)
|
||||||
android_spawn_dep = cc.find_library('android-spawn', required : false)
|
android_spawn_dep = cc.find_library('android-spawn', required : false)
|
||||||
@@ -173,18 +164,11 @@ mainclient_src = [
|
|||||||
'src/mainclient/shell.c'
|
'src/mainclient/shell.c'
|
||||||
]
|
]
|
||||||
|
|
||||||
janet_dependencies = [m_dep, dl_dep, android_spawn_dep]
|
|
||||||
janet_native_dependencies = [native_m_dep, native_dl_dep, native_android_spawn_dep]
|
|
||||||
if not get_option('single_threaded')
|
|
||||||
janet_dependencies += thread_dep
|
|
||||||
janet_native_dependencies += native_thread_dep
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Build boot binary
|
# Build boot binary
|
||||||
janet_boot = executable('janet-boot', core_src, boot_src,
|
janet_boot = executable('janet-boot', core_src, boot_src,
|
||||||
include_directories : incdir,
|
include_directories : incdir,
|
||||||
c_args : '-DJANET_BOOTSTRAP',
|
c_args : '-DJANET_BOOTSTRAP',
|
||||||
dependencies : janet_native_dependencies,
|
dependencies : [m_dep, dl_dep, thread_dep, android_spawn_dep],
|
||||||
native : true)
|
native : true)
|
||||||
|
|
||||||
# Build janet.c
|
# Build janet.c
|
||||||
@@ -197,6 +181,11 @@ janetc = custom_target('janetc',
|
|||||||
'JANET_PATH', janet_path
|
'JANET_PATH', janet_path
|
||||||
])
|
])
|
||||||
|
|
||||||
|
janet_dependencies = [m_dep, dl_dep, android_spawn_dep]
|
||||||
|
if not get_option('single_threaded')
|
||||||
|
janet_dependencies += thread_dep
|
||||||
|
endif
|
||||||
|
|
||||||
# Allow building with no shared library
|
# Allow building with no shared library
|
||||||
if cc.has_argument('-fvisibility=hidden')
|
if cc.has_argument('-fvisibility=hidden')
|
||||||
lib_cflags = ['-fvisibility=hidden']
|
lib_cflags = ['-fvisibility=hidden']
|
||||||
@@ -242,7 +231,7 @@ if meson.is_cross_build()
|
|||||||
endif
|
endif
|
||||||
janet_nativeclient = executable('janet-native', janetc, mainclient_src,
|
janet_nativeclient = executable('janet-native', janetc, mainclient_src,
|
||||||
include_directories : incdir,
|
include_directories : incdir,
|
||||||
dependencies : janet_native_dependencies,
|
dependencies : janet_dependencies,
|
||||||
c_args : extra_native_cflags,
|
c_args : extra_native_cflags,
|
||||||
native : true)
|
native : true)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -204,16 +204,6 @@
|
|||||||
[fmt & args]
|
[fmt & args]
|
||||||
(error (string/format fmt ;args)))
|
(error (string/format fmt ;args)))
|
||||||
|
|
||||||
(defmacro assertf
|
|
||||||
"Convenience macro that combines `assert` and `string/format`."
|
|
||||||
[x fmt & args]
|
|
||||||
(def v (gensym))
|
|
||||||
~(do
|
|
||||||
(def ,v ,x)
|
|
||||||
(if ,v
|
|
||||||
,v
|
|
||||||
(,errorf ,fmt ,;args))))
|
|
||||||
|
|
||||||
(defmacro default
|
(defmacro default
|
||||||
``Define a default value for an optional argument.
|
``Define a default value for an optional argument.
|
||||||
Expands to `(def sym (if (= nil sym) val sym))`.``
|
Expands to `(def sym (if (= nil sym) val sym))`.``
|
||||||
@@ -1863,9 +1853,6 @@
|
|||||||
(defdyn *pretty-format*
|
(defdyn *pretty-format*
|
||||||
"Format specifier for the `pp` function")
|
"Format specifier for the `pp` function")
|
||||||
|
|
||||||
(defdyn *repl-prompt*
|
|
||||||
"Allow setting a custom prompt at the default REPL. Not all REPLs will respect this binding.")
|
|
||||||
|
|
||||||
(defn pp
|
(defn pp
|
||||||
``Pretty-print to stdout or `(dyn *out*)`. The format string used is `(dyn *pretty-format* "%q")`.``
|
``Pretty-print to stdout or `(dyn *out*)`. The format string used is `(dyn *pretty-format* "%q")`.``
|
||||||
[x]
|
[x]
|
||||||
@@ -2219,6 +2206,43 @@
|
|||||||
(map-template :some res pred ind inds)
|
(map-template :some res pred ind inds)
|
||||||
res)
|
res)
|
||||||
|
|
||||||
|
(defn deep-not=
|
||||||
|
``Like `not=`, but mutable types (arrays, tables, buffers) are considered
|
||||||
|
equal if they have identical structure. Much slower than `not=`.``
|
||||||
|
[x y]
|
||||||
|
(def tx (type x))
|
||||||
|
(or
|
||||||
|
(not= tx (type y))
|
||||||
|
(case tx
|
||||||
|
:tuple (or (not= (length x) (length y))
|
||||||
|
(do
|
||||||
|
(var ret false)
|
||||||
|
(forv i 0 (length x)
|
||||||
|
(def xx (in x i))
|
||||||
|
(def yy (in y i))
|
||||||
|
(if (deep-not= xx yy)
|
||||||
|
(break (set ret true))))
|
||||||
|
ret))
|
||||||
|
:array (or (not= (length x) (length y))
|
||||||
|
(do
|
||||||
|
(var ret false)
|
||||||
|
(forv i 0 (length x)
|
||||||
|
(def xx (in x i))
|
||||||
|
(def yy (in y i))
|
||||||
|
(if (deep-not= xx yy)
|
||||||
|
(break (set ret true))))
|
||||||
|
ret))
|
||||||
|
:struct (deep-not= (kvs x) (kvs y))
|
||||||
|
:table (deep-not= (table/to-struct x) (table/to-struct y))
|
||||||
|
:buffer (not= (string x) (string y))
|
||||||
|
(not= x y))))
|
||||||
|
|
||||||
|
(defn deep=
|
||||||
|
``Like `=`, but mutable types (arrays, tables, buffers) are considered
|
||||||
|
equal if they have identical structure. Much slower than `=`.``
|
||||||
|
[x y]
|
||||||
|
(not (deep-not= x y)))
|
||||||
|
|
||||||
(defn freeze
|
(defn freeze
|
||||||
`Freeze an object (make it immutable) and do a deep copy, making
|
`Freeze an object (make it immutable) and do a deep copy, making
|
||||||
child values also immutable. Closures, fibers, and abstract types
|
child values also immutable. Closures, fibers, and abstract types
|
||||||
@@ -2247,43 +2271,6 @@
|
|||||||
:string (buffer ds)
|
:string (buffer ds)
|
||||||
ds))
|
ds))
|
||||||
|
|
||||||
(defn deep-not=
|
|
||||||
``Like `not=`, but mutable types (arrays, tables, buffers) are considered
|
|
||||||
equal if they have identical structure. Much slower than `not=`.``
|
|
||||||
[x y]
|
|
||||||
(def tx (type x))
|
|
||||||
(or
|
|
||||||
(not= tx (type y))
|
|
||||||
(cond
|
|
||||||
(or (= tx :tuple) (= tx :array))
|
|
||||||
(or (not= (length x) (length y))
|
|
||||||
(do
|
|
||||||
(var ret false)
|
|
||||||
(forv i 0 (length x)
|
|
||||||
(def xx (in x i))
|
|
||||||
(def yy (in y i))
|
|
||||||
(if (deep-not= xx yy)
|
|
||||||
(break (set ret true))))
|
|
||||||
ret))
|
|
||||||
(or (= tx :struct) (= tx :table))
|
|
||||||
(or (not= (length x) (length y))
|
|
||||||
(do
|
|
||||||
(def rawget (if (= tx :table) table/rawget struct/rawget))
|
|
||||||
(var ret false)
|
|
||||||
(eachp [k v] x
|
|
||||||
(def yv (rawget y k))
|
|
||||||
(if (= nil yv) (break (set ret true)))
|
|
||||||
(if (deep-not= yv v) (break (set ret true))))
|
|
||||||
ret))
|
|
||||||
(= tx :buffer) (not= 0 (- (length x) (length y)) (memcmp x y))
|
|
||||||
(not= x y))))
|
|
||||||
|
|
||||||
(defn deep=
|
|
||||||
``Like `=`, but mutable types (arrays, tables, buffers) are considered
|
|
||||||
equal if they have identical structure. Much slower than `=`.``
|
|
||||||
[x y]
|
|
||||||
(not (deep-not= x y)))
|
|
||||||
|
|
||||||
(defn macex
|
(defn macex
|
||||||
``Expand macros completely.
|
``Expand macros completely.
|
||||||
`on-binding` is an optional callback for whenever a normal symbolic binding
|
`on-binding` is an optional callback for whenever a normal symbolic binding
|
||||||
@@ -2665,6 +2652,7 @@
|
|||||||
|
|
||||||
(do
|
(do
|
||||||
(var pindex 0)
|
(var pindex 0)
|
||||||
|
(var pstatus nil)
|
||||||
(def len (length buf))
|
(def len (length buf))
|
||||||
(when (= len 0)
|
(when (= len 0)
|
||||||
(:eof p)
|
(:eof p)
|
||||||
@@ -2839,24 +2827,6 @@
|
|||||||
(array/insert mp curall-index [(string ":cur:/:all:" ext) loader check-relative])
|
(array/insert mp curall-index [(string ":cur:/:all:" ext) loader check-relative])
|
||||||
mp)
|
mp)
|
||||||
|
|
||||||
# Don't expose this externally yet - could break if custom module/paths is setup.
|
|
||||||
(defn- module/add-syspath
|
|
||||||
```
|
|
||||||
Add a custom syspath to `module/paths` by duplicating all entries that being with `:sys:` and
|
|
||||||
adding duplicates with a specific path prefix instead.
|
|
||||||
```
|
|
||||||
[path]
|
|
||||||
(def copies @[])
|
|
||||||
(var last-index 0)
|
|
||||||
(def mp (dyn *module-paths* module/paths))
|
|
||||||
(eachp [index entry] mp
|
|
||||||
(def pattern (first entry))
|
|
||||||
(when (and (string? pattern) (string/has-prefix? ":sys:/" pattern))
|
|
||||||
(set last-index index)
|
|
||||||
(array/push copies [(string/replace ":sys:" path pattern) ;(drop 1 entry)])))
|
|
||||||
(array/insert mp (+ 1 last-index) ;copies)
|
|
||||||
mp)
|
|
||||||
|
|
||||||
(module/add-paths ":native:" :native)
|
(module/add-paths ":native:" :native)
|
||||||
(module/add-paths "/init.janet" :source)
|
(module/add-paths "/init.janet" :source)
|
||||||
(module/add-paths ".janet" :source)
|
(module/add-paths ".janet" :source)
|
||||||
@@ -3943,7 +3913,7 @@
|
|||||||
(defn make-sig []
|
(defn make-sig []
|
||||||
(ffi/signature :default real-ret-type ;computed-type-args))
|
(ffi/signature :default real-ret-type ;computed-type-args))
|
||||||
(defn make-ptr []
|
(defn make-ptr []
|
||||||
(assertf (ffi/lookup (if lazy (llib) lib) raw-symbol) "failed to find ffi symbol %v" raw-symbol))
|
(assert (ffi/lookup (if lazy (llib) lib) raw-symbol) (string "failed to find ffi symbol " raw-symbol)))
|
||||||
(if lazy
|
(if lazy
|
||||||
~(defn ,alias ,;meta [,;formal-args]
|
~(defn ,alias ,;meta [,;formal-args]
|
||||||
(,ffi/call (,(delay (make-ptr))) (,(delay (make-sig))) ,;formal-args))
|
(,ffi/call (,(delay (make-ptr))) (,(delay (make-sig))) ,;formal-args))
|
||||||
@@ -4086,18 +4056,15 @@
|
|||||||
|
|
||||||
(defn- copyfile
|
(defn- copyfile
|
||||||
[from to]
|
[from to]
|
||||||
(if-with [ffrom (file/open from :rb)]
|
(def mode (os/stat from :permissions))
|
||||||
(if-with [fto (file/open to :wb)]
|
(def b (buffer/new 0x10000))
|
||||||
(do
|
(with [ffrom (file/open from :rb)]
|
||||||
(def perm (os/stat from :permissions))
|
(with [fto (file/open to :wb)]
|
||||||
(def b (buffer/new 0x10000))
|
(forever
|
||||||
(forever
|
(file/read ffrom 0x10000 b)
|
||||||
(file/read ffrom 0x10000 b)
|
(when (empty? b) (buffer/trim b) (os/chmod to mode) (break))
|
||||||
(when (empty? b) (buffer/trim b) (os/chmod to perm) (break))
|
(file/write fto b)
|
||||||
(file/write fto b)
|
(buffer/clear b)))))
|
||||||
(buffer/clear b)))
|
|
||||||
(errorf "destination file %s cannot be opened for writing" to))
|
|
||||||
(errorf "source file %s cannot be opened for reading" from)))
|
|
||||||
|
|
||||||
(defn- copyrf
|
(defn- copyrf
|
||||||
[from to]
|
[from to]
|
||||||
@@ -4120,7 +4087,7 @@
|
|||||||
"Get the manifest for a give installed bundle"
|
"Get the manifest for a give installed bundle"
|
||||||
[bundle-name]
|
[bundle-name]
|
||||||
(def name (get-manifest-filename bundle-name))
|
(def name (get-manifest-filename bundle-name))
|
||||||
(assertf (fexists name) "no bundle %v found" bundle-name)
|
(assert (fexists name) (string "no bundle " bundle-name " found"))
|
||||||
(parse (slurp name)))
|
(parse (slurp name)))
|
||||||
|
|
||||||
(defn- get-bundle-module
|
(defn- get-bundle-module
|
||||||
@@ -4263,9 +4230,11 @@
|
|||||||
(def missing (seq [d :in deps :when (not (bundle/installed? d))] (string d)))
|
(def missing (seq [d :in deps :when (not (bundle/installed? d))] (string d)))
|
||||||
(when (next missing) (errorf "missing dependencies %s" (string/join missing ", "))))
|
(when (next missing) (errorf "missing dependencies %s" (string/join missing ", "))))
|
||||||
(def bundle-name (get config :name default-bundle-name))
|
(def bundle-name (get config :name default-bundle-name))
|
||||||
(assertf bundle-name "unable to infer bundle name for %v, use :name argument" path)
|
(assert bundle-name (errorf "unable to infer bundle name for %v, use :name argument" path))
|
||||||
(assertf (not (string/check-set "\\/" bundle-name))
|
(assert (not (string/check-set "\\/" bundle-name))
|
||||||
"bundle name %v cannot contain path separators" bundle-name)
|
(string "bundle name "
|
||||||
|
bundle-name
|
||||||
|
" cannot contain path separators"))
|
||||||
(assert (next bundle-name) "cannot use empty bundle-name")
|
(assert (next bundle-name) "cannot use empty bundle-name")
|
||||||
(assert (not (fexists (get-manifest-filename bundle-name)))
|
(assert (not (fexists (get-manifest-filename bundle-name)))
|
||||||
"bundle is already installed")
|
"bundle is already installed")
|
||||||
@@ -4302,10 +4271,10 @@
|
|||||||
(do-hook module bundle-name :clean man))
|
(do-hook module bundle-name :clean man))
|
||||||
(do-hook module bundle-name :build man)
|
(do-hook module bundle-name :build man)
|
||||||
(do-hook module bundle-name :install man)
|
(do-hook module bundle-name :install man)
|
||||||
(if (empty? (get man :files)) (print "no files installed, is this a valid bundle?"))
|
|
||||||
(sync-manifest man)
|
|
||||||
(when check
|
(when check
|
||||||
(do-hook module bundle-name :check man)))
|
(do-hook module bundle-name :check man))
|
||||||
|
(if (empty? (get man :files)) (print "no files installed, is this a valid bundle?"))
|
||||||
|
(sync-manifest man))
|
||||||
(print "installed " bundle-name)
|
(print "installed " bundle-name)
|
||||||
bundle-name)
|
bundle-name)
|
||||||
|
|
||||||
@@ -4317,7 +4286,7 @@
|
|||||||
(var i 0)
|
(var i 0)
|
||||||
(def man (bundle/manifest bundle-name))
|
(def man (bundle/manifest bundle-name))
|
||||||
(def files (get man :files @[]))
|
(def files (get man :files @[]))
|
||||||
(assertf (os/mkdir dest-dir) "could not create directory %v (or it already exists)" dest-dir)
|
(assert (os/mkdir dest-dir) (string "could not create directory " dest-dir " (or it already exists)"))
|
||||||
(def s (sep))
|
(def s (sep))
|
||||||
(os/mkdir (string dest-dir s "bundle"))
|
(os/mkdir (string dest-dir s "bundle"))
|
||||||
(def install-hook (string dest-dir s "bundle" s "init.janet"))
|
(def install-hook (string dest-dir s "bundle" s "init.janet"))
|
||||||
@@ -4413,15 +4382,12 @@
|
|||||||
[manifest src &opt dest chmod-mode]
|
[manifest src &opt dest chmod-mode]
|
||||||
(default dest src)
|
(default dest src)
|
||||||
(def s (sep))
|
(def s (sep))
|
||||||
(def mode (os/stat src :mode))
|
(case (os/stat src :mode)
|
||||||
(if-not mode (errorf "file %s does not exist" src))
|
|
||||||
(case mode
|
|
||||||
:directory
|
:directory
|
||||||
(let [absdest (bundle/add-directory manifest dest chmod-mode)]
|
(let [absdest (bundle/add-directory manifest dest chmod-mode)]
|
||||||
(each d (os/dir src) (bundle/add manifest (string src s d) (string dest s d) chmod-mode))
|
(each d (os/dir src) (bundle/add manifest (string src s d) (string dest s d) chmod-mode))
|
||||||
absdest)
|
absdest)
|
||||||
:file (bundle/add-file manifest src dest chmod-mode)
|
:file (bundle/add-file manifest src dest chmod-mode)))
|
||||||
(errorf "bad path %s - file is a %s" src mode)))
|
|
||||||
|
|
||||||
(defn bundle/add-bin
|
(defn bundle/add-bin
|
||||||
`Shorthand for adding scripts during an install. Scripts will be installed to
|
`Shorthand for adding scripts during an install. Scripts will be installed to
|
||||||
@@ -4516,12 +4482,7 @@
|
|||||||
(var error-level nil)
|
(var error-level nil)
|
||||||
(var expect-image false)
|
(var expect-image false)
|
||||||
|
|
||||||
(when-let [jp (getenv-alias "JANET_PATH")]
|
(if-let [jp (getenv-alias "JANET_PATH")] (setdyn *syspath* jp))
|
||||||
(def path-sep (if (index-of (os/which) [:windows :mingw]) ";" ":"))
|
|
||||||
(def paths (reverse! (string/split path-sep jp)))
|
|
||||||
(for i 1 (length paths)
|
|
||||||
(module/add-syspath (get paths i)))
|
|
||||||
(setdyn *syspath* (first paths)))
|
|
||||||
(if-let [jprofile (getenv-alias "JANET_PROFILE")] (setdyn *profilepath* jprofile))
|
(if-let [jprofile (getenv-alias "JANET_PROFILE")] (setdyn *profilepath* jprofile))
|
||||||
(set colorize (and
|
(set colorize (and
|
||||||
(not (getenv-alias "NO_COLOR"))
|
(not (getenv-alias "NO_COLOR"))
|
||||||
@@ -4653,15 +4614,17 @@
|
|||||||
(if-not quiet
|
(if-not quiet
|
||||||
(print "Janet " janet/version "-" janet/build " " (os/which) "/" (os/arch) "/" (os/compiler) " - '(doc)' for help"))
|
(print "Janet " janet/version "-" janet/build " " (os/which) "/" (os/arch) "/" (os/compiler) " - '(doc)' for help"))
|
||||||
(flush)
|
(flush)
|
||||||
(def env (make-env))
|
|
||||||
(defn getprompt [p]
|
(defn getprompt [p]
|
||||||
(when-let [custom-prompt (get env *repl-prompt*)] (break (custom-prompt p)))
|
|
||||||
(def [line] (parser/where p))
|
(def [line] (parser/where p))
|
||||||
(string "repl:" line ":" (parser/state p :delimiters) "> "))
|
(string "repl:" line ":" (parser/state p :delimiters) "> "))
|
||||||
(defn getstdin [prompt buf _]
|
(defn getstdin [prompt buf _]
|
||||||
(file/write stdout prompt)
|
(file/write stdout prompt)
|
||||||
(file/flush stdout)
|
(file/flush stdout)
|
||||||
(file/read stdin :line buf))
|
(file/read stdin :line buf))
|
||||||
|
(def env (make-env))
|
||||||
|
(when-let [profile.janet (dyn *profilepath*)]
|
||||||
|
(def new-env (dofile profile.janet :exit true))
|
||||||
|
(merge-module env new-env "" false))
|
||||||
(when debug-flag
|
(when debug-flag
|
||||||
(put env *debug* true)
|
(put env *debug* true)
|
||||||
(put env *redef* true))
|
(put env *redef* true))
|
||||||
@@ -4673,9 +4636,6 @@
|
|||||||
(setdyn *doc-color* (if colorize true))
|
(setdyn *doc-color* (if colorize true))
|
||||||
(setdyn *lint-error* error-level)
|
(setdyn *lint-error* error-level)
|
||||||
(setdyn *lint-warn* error-level)
|
(setdyn *lint-warn* error-level)
|
||||||
(when-let [profile.janet (dyn *profilepath*)]
|
|
||||||
(dofile profile.janet :exit true :env env)
|
|
||||||
(put env *current-file* nil))
|
|
||||||
(repl getchunk nil env)))))
|
(repl getchunk nil env)))))
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -4,10 +4,10 @@
|
|||||||
#define JANETCONF_H
|
#define JANETCONF_H
|
||||||
|
|
||||||
#define JANET_VERSION_MAJOR 1
|
#define JANET_VERSION_MAJOR 1
|
||||||
#define JANET_VERSION_MINOR 37
|
#define JANET_VERSION_MINOR 36
|
||||||
#define JANET_VERSION_PATCH 1
|
#define JANET_VERSION_PATCH 0
|
||||||
#define JANET_VERSION_EXTRA ""
|
#define JANET_VERSION_EXTRA "-dev"
|
||||||
#define JANET_VERSION "1.37.1"
|
#define JANET_VERSION "1.36.0-dev"
|
||||||
|
|
||||||
/* #define JANET_BUILD "local" */
|
/* #define JANET_BUILD "local" */
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -371,15 +371,17 @@ JANET_CORE_FN(cfun_buffer_push_uint16,
|
|||||||
janet_fixarity(argc, 3);
|
janet_fixarity(argc, 3);
|
||||||
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
||||||
int reverse = should_reverse_bytes(argv, 1);
|
int reverse = should_reverse_bytes(argv, 1);
|
||||||
uint16_t data = janet_getuinteger16(argv, 2);
|
union {
|
||||||
uint8_t bytes[sizeof(data)];
|
uint16_t data;
|
||||||
memcpy(bytes, &data, sizeof(bytes));
|
uint8_t bytes[2];
|
||||||
|
} u;
|
||||||
|
u.data = janet_getuinteger16(argv, 2);
|
||||||
if (reverse) {
|
if (reverse) {
|
||||||
uint8_t temp = bytes[1];
|
uint8_t temp = u.bytes[1];
|
||||||
bytes[1] = bytes[0];
|
u.bytes[1] = u.bytes[0];
|
||||||
bytes[0] = temp;
|
u.bytes[0] = temp;
|
||||||
}
|
}
|
||||||
janet_buffer_push_bytes(buffer, bytes, sizeof(bytes));
|
janet_buffer_push_u16(buffer, *(uint16_t *) u.bytes);
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,12 +392,14 @@ JANET_CORE_FN(cfun_buffer_push_uint32,
|
|||||||
janet_fixarity(argc, 3);
|
janet_fixarity(argc, 3);
|
||||||
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
||||||
int reverse = should_reverse_bytes(argv, 1);
|
int reverse = should_reverse_bytes(argv, 1);
|
||||||
uint32_t data = janet_getuinteger(argv, 2);
|
union {
|
||||||
uint8_t bytes[sizeof(data)];
|
uint32_t data;
|
||||||
memcpy(bytes, &data, sizeof(bytes));
|
uint8_t bytes[4];
|
||||||
|
} u;
|
||||||
|
u.data = janet_getuinteger(argv, 2);
|
||||||
if (reverse)
|
if (reverse)
|
||||||
reverse_u32(bytes);
|
reverse_u32(u.bytes);
|
||||||
janet_buffer_push_bytes(buffer, bytes, sizeof(bytes));
|
janet_buffer_push_u32(buffer, *(uint32_t *) u.bytes);
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,12 +410,14 @@ JANET_CORE_FN(cfun_buffer_push_uint64,
|
|||||||
janet_fixarity(argc, 3);
|
janet_fixarity(argc, 3);
|
||||||
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
||||||
int reverse = should_reverse_bytes(argv, 1);
|
int reverse = should_reverse_bytes(argv, 1);
|
||||||
uint64_t data = janet_getuinteger64(argv, 2);
|
union {
|
||||||
uint8_t bytes[sizeof(data)];
|
uint64_t data;
|
||||||
memcpy(bytes, &data, sizeof(bytes));
|
uint8_t bytes[8];
|
||||||
|
} u;
|
||||||
|
u.data = janet_getuinteger64(argv, 2);
|
||||||
if (reverse)
|
if (reverse)
|
||||||
reverse_u64(bytes);
|
reverse_u64(u.bytes);
|
||||||
janet_buffer_push_bytes(buffer, bytes, sizeof(bytes));
|
janet_buffer_push_u64(buffer, *(uint64_t *) u.bytes);
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,12 +428,14 @@ JANET_CORE_FN(cfun_buffer_push_float32,
|
|||||||
janet_fixarity(argc, 3);
|
janet_fixarity(argc, 3);
|
||||||
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
||||||
int reverse = should_reverse_bytes(argv, 1);
|
int reverse = should_reverse_bytes(argv, 1);
|
||||||
float data = (float) janet_getnumber(argv, 2);
|
union {
|
||||||
uint8_t bytes[sizeof(data)];
|
float data;
|
||||||
memcpy(bytes, &data, sizeof(bytes));
|
uint8_t bytes[4];
|
||||||
|
} u;
|
||||||
|
u.data = (float) janet_getnumber(argv, 2);
|
||||||
if (reverse)
|
if (reverse)
|
||||||
reverse_u32(bytes);
|
reverse_u32(u.bytes);
|
||||||
janet_buffer_push_bytes(buffer, bytes, sizeof(bytes));
|
janet_buffer_push_u32(buffer, *(uint32_t *) u.bytes);
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,12 +446,14 @@ JANET_CORE_FN(cfun_buffer_push_float64,
|
|||||||
janet_fixarity(argc, 3);
|
janet_fixarity(argc, 3);
|
||||||
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
JanetBuffer *buffer = janet_getbuffer(argv, 0);
|
||||||
int reverse = should_reverse_bytes(argv, 1);
|
int reverse = should_reverse_bytes(argv, 1);
|
||||||
double data = janet_getnumber(argv, 2);
|
union {
|
||||||
uint8_t bytes[sizeof(data)];
|
double data;
|
||||||
memcpy(bytes, &data, sizeof(bytes));
|
uint8_t bytes[8];
|
||||||
|
} u;
|
||||||
|
u.data = janet_getnumber(argv, 2);
|
||||||
if (reverse)
|
if (reverse)
|
||||||
reverse_u64(bytes);
|
reverse_u64(u.bytes);
|
||||||
janet_buffer_push_bytes(buffer, bytes, sizeof(bytes));
|
janet_buffer_push_u64(buffer, *(uint64_t *) u.bytes);
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -31,12 +31,10 @@
|
|||||||
#ifndef JANET_SINGLE_THREADED
|
#ifndef JANET_SINGLE_THREADED
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#else
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef JANET_WINDOWS
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef JANET_USE_STDATOMIC
|
#ifdef JANET_USE_STDATOMIC
|
||||||
#include <stdatomic.h>
|
#include <stdatomic.h>
|
||||||
@@ -62,13 +60,6 @@ JANET_NO_RETURN static void janet_top_level_signal(const char *msg) {
|
|||||||
|
|
||||||
void janet_signalv(JanetSignal sig, Janet message) {
|
void janet_signalv(JanetSignal sig, Janet message) {
|
||||||
if (janet_vm.return_reg != NULL) {
|
if (janet_vm.return_reg != NULL) {
|
||||||
/* Should match logic in janet_call for coercing everything not ok to an error (no awaits, yields, etc.) */
|
|
||||||
if (janet_vm.coerce_error && sig != JANET_SIGNAL_OK) {
|
|
||||||
if (sig != JANET_SIGNAL_ERROR) {
|
|
||||||
message = janet_wrap_string(janet_formatc("%v coerced from %s to error", message, janet_signal_names[sig]));
|
|
||||||
}
|
|
||||||
sig = JANET_SIGNAL_ERROR;
|
|
||||||
}
|
|
||||||
*janet_vm.return_reg = message;
|
*janet_vm.return_reg = message;
|
||||||
if (NULL != janet_vm.fiber) {
|
if (NULL != janet_vm.fiber) {
|
||||||
janet_vm.fiber->flags |= JANET_FIBER_DID_LONGJUMP;
|
janet_vm.fiber->flags |= JANET_FIBER_DID_LONGJUMP;
|
||||||
@@ -555,8 +546,8 @@ void *janet_optabstract(const Janet *argv, int32_t argc, int32_t n, const JanetA
|
|||||||
/* Atomic refcounts */
|
/* Atomic refcounts */
|
||||||
|
|
||||||
JanetAtomicInt janet_atomic_inc(JanetAtomicInt volatile *x) {
|
JanetAtomicInt janet_atomic_inc(JanetAtomicInt volatile *x) {
|
||||||
#ifdef _MSC_VER
|
#ifdef JANET_WINDOWS
|
||||||
return _InterlockedIncrement(x);
|
return InterlockedIncrement(x);
|
||||||
#elif defined(JANET_USE_STDATOMIC)
|
#elif defined(JANET_USE_STDATOMIC)
|
||||||
return atomic_fetch_add_explicit(x, 1, memory_order_relaxed) + 1;
|
return atomic_fetch_add_explicit(x, 1, memory_order_relaxed) + 1;
|
||||||
#else
|
#else
|
||||||
@@ -565,8 +556,8 @@ JanetAtomicInt janet_atomic_inc(JanetAtomicInt volatile *x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JanetAtomicInt janet_atomic_dec(JanetAtomicInt volatile *x) {
|
JanetAtomicInt janet_atomic_dec(JanetAtomicInt volatile *x) {
|
||||||
#ifdef _MSC_VER
|
#ifdef JANET_WINDOWS
|
||||||
return _InterlockedDecrement(x);
|
return InterlockedDecrement(x);
|
||||||
#elif defined(JANET_USE_STDATOMIC)
|
#elif defined(JANET_USE_STDATOMIC)
|
||||||
return atomic_fetch_add_explicit(x, -1, memory_order_acq_rel) - 1;
|
return atomic_fetch_add_explicit(x, -1, memory_order_acq_rel) - 1;
|
||||||
#else
|
#else
|
||||||
@@ -575,8 +566,8 @@ JanetAtomicInt janet_atomic_dec(JanetAtomicInt volatile *x) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JanetAtomicInt janet_atomic_load(JanetAtomicInt volatile *x) {
|
JanetAtomicInt janet_atomic_load(JanetAtomicInt volatile *x) {
|
||||||
#ifdef _MSC_VER
|
#ifdef JANET_WINDOWS
|
||||||
return _InterlockedOr(x, 0);
|
return InterlockedOr(x, 0);
|
||||||
#elif defined(JANET_USE_STDATOMIC)
|
#elif defined(JANET_USE_STDATOMIC)
|
||||||
return atomic_load_explicit(x, memory_order_acquire);
|
return atomic_load_explicit(x, memory_order_acquire);
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -700,15 +700,7 @@ JANET_CORE_FN(janet_core_is_lengthable,
|
|||||||
|
|
||||||
JANET_CORE_FN(janet_core_signal,
|
JANET_CORE_FN(janet_core_signal,
|
||||||
"(signal what x)",
|
"(signal what x)",
|
||||||
"Raise a signal with payload x. `what` can be an integer\n"
|
"Raise a signal with payload x. ") {
|
||||||
"from 0 through 7 indicating user(0-7), or one of:\n\n"
|
|
||||||
"* :ok\n"
|
|
||||||
"* :error\n"
|
|
||||||
"* :debug\n"
|
|
||||||
"* :yield\n"
|
|
||||||
"* :user(0-7)\n"
|
|
||||||
"* :interrupt\n"
|
|
||||||
"* :await") {
|
|
||||||
janet_arity(argc, 1, 2);
|
janet_arity(argc, 1, 2);
|
||||||
Janet payload = argc == 2 ? argv[1] : janet_wrap_nil();
|
Janet payload = argc == 2 ? argv[1] : janet_wrap_nil();
|
||||||
if (janet_checkint(argv[0])) {
|
if (janet_checkint(argv[0])) {
|
||||||
@@ -1001,12 +993,12 @@ static void make_apply(JanetTable *env) {
|
|||||||
janet_quick_asm(env, JANET_FUN_APPLY | JANET_FUNCDEF_FLAG_VARARG,
|
janet_quick_asm(env, JANET_FUN_APPLY | JANET_FUNCDEF_FLAG_VARARG,
|
||||||
"apply", 1, 1, INT32_MAX, 6, apply_asm, sizeof(apply_asm),
|
"apply", 1, 1, INT32_MAX, 6, apply_asm, sizeof(apply_asm),
|
||||||
JDOC("(apply f & args)\n\n"
|
JDOC("(apply f & args)\n\n"
|
||||||
"Applies a function to a variable number of arguments. Each element in args "
|
"Applies a function to a variable number of arguments. Each element in args "
|
||||||
"is used as an argument to f, except the last element in args, which is expected to "
|
"is used as an argument to f, except the last element in args, which is expected to "
|
||||||
"be an array-like. Each element in this last argument is then also pushed as an argument to "
|
"be an array-like. Each element in this last argument is then also pushed as an argument to "
|
||||||
"f. For example:\n\n"
|
"f. For example:\n\n"
|
||||||
"\t(apply + 1000 (range 10))\n\n"
|
"\t(apply + 1000 (range 10))\n\n"
|
||||||
"sums the first 10 integers and 1000."));
|
"sums the first 10 integers and 1000."));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t error_asm[] = {
|
static const uint32_t error_asm[] = {
|
||||||
@@ -1159,82 +1151,82 @@ JanetTable *janet_core_env(JanetTable *replacements) {
|
|||||||
janet_quick_asm(env, JANET_FUN_CMP,
|
janet_quick_asm(env, JANET_FUN_CMP,
|
||||||
"cmp", 2, 2, 2, 2, cmp_asm, sizeof(cmp_asm),
|
"cmp", 2, 2, 2, 2, cmp_asm, sizeof(cmp_asm),
|
||||||
JDOC("(cmp x y)\n\n"
|
JDOC("(cmp x y)\n\n"
|
||||||
"Returns -1 if x is strictly less than y, 1 if y is strictly greater "
|
"Returns -1 if x is strictly less than y, 1 if y is strictly greater "
|
||||||
"than x, and 0 otherwise. To return 0, x and y must be the exact same type."));
|
"than x, and 0 otherwise. To return 0, x and y must be the exact same type."));
|
||||||
janet_quick_asm(env, JANET_FUN_NEXT,
|
janet_quick_asm(env, JANET_FUN_NEXT,
|
||||||
"next", 2, 1, 2, 2, next_asm, sizeof(next_asm),
|
"next", 2, 1, 2, 2, next_asm, sizeof(next_asm),
|
||||||
JDOC("(next ds &opt key)\n\n"
|
JDOC("(next ds &opt key)\n\n"
|
||||||
"Gets the next key in a data structure. Can be used to iterate through "
|
"Gets the next key in a data structure. Can be used to iterate through "
|
||||||
"the keys of a data structure in an unspecified order. Keys are guaranteed "
|
"the keys of a data structure in an unspecified order. Keys are guaranteed "
|
||||||
"to be seen only once per iteration if the data structure is not mutated "
|
"to be seen only once per iteration if the data structure is not mutated "
|
||||||
"during iteration. If key is nil, next returns the first key. If next "
|
"during iteration. If key is nil, next returns the first key. If next "
|
||||||
"returns nil, there are no more keys to iterate through."));
|
"returns nil, there are no more keys to iterate through."));
|
||||||
janet_quick_asm(env, JANET_FUN_PROP,
|
janet_quick_asm(env, JANET_FUN_PROP,
|
||||||
"propagate", 2, 2, 2, 2, propagate_asm, sizeof(propagate_asm),
|
"propagate", 2, 2, 2, 2, propagate_asm, sizeof(propagate_asm),
|
||||||
JDOC("(propagate x fiber)\n\n"
|
JDOC("(propagate x fiber)\n\n"
|
||||||
"Propagate a signal from a fiber to the current fiber and "
|
"Propagate a signal from a fiber to the current fiber and "
|
||||||
"set the last value of the current fiber to `x`. The signal "
|
"set the last value of the current fiber to `x`. The signal "
|
||||||
"value is then available as the status of the current fiber. "
|
"value is then available as the status of the current fiber. "
|
||||||
"The resulting stack trace from the current fiber will include "
|
"The resulting stack trace from the current fiber will include "
|
||||||
"frames from fiber. If fiber is in a state that can be resumed, "
|
"frames from fiber. If fiber is in a state that can be resumed, "
|
||||||
"resuming the current fiber will first resume `fiber`. "
|
"resuming the current fiber will first resume `fiber`. "
|
||||||
"This function can be used to re-raise an error without losing "
|
"This function can be used to re-raise an error without losing "
|
||||||
"the original stack trace."));
|
"the original stack trace."));
|
||||||
janet_quick_asm(env, JANET_FUN_DEBUG,
|
janet_quick_asm(env, JANET_FUN_DEBUG,
|
||||||
"debug", 1, 0, 1, 1, debug_asm, sizeof(debug_asm),
|
"debug", 1, 0, 1, 1, debug_asm, sizeof(debug_asm),
|
||||||
JDOC("(debug &opt x)\n\n"
|
JDOC("(debug &opt x)\n\n"
|
||||||
"Throws a debug signal that can be caught by a parent fiber and used to inspect "
|
"Throws a debug signal that can be caught by a parent fiber and used to inspect "
|
||||||
"the running state of the current fiber. Returns the value passed in by resume."));
|
"the running state of the current fiber. Returns the value passed in by resume."));
|
||||||
janet_quick_asm(env, JANET_FUN_ERROR,
|
janet_quick_asm(env, JANET_FUN_ERROR,
|
||||||
"error", 1, 1, 1, 1, error_asm, sizeof(error_asm),
|
"error", 1, 1, 1, 1, error_asm, sizeof(error_asm),
|
||||||
JDOC("(error e)\n\n"
|
JDOC("(error e)\n\n"
|
||||||
"Throws an error e that can be caught and handled by a parent fiber."));
|
"Throws an error e that can be caught and handled by a parent fiber."));
|
||||||
janet_quick_asm(env, JANET_FUN_YIELD,
|
janet_quick_asm(env, JANET_FUN_YIELD,
|
||||||
"yield", 1, 0, 1, 2, yield_asm, sizeof(yield_asm),
|
"yield", 1, 0, 1, 2, yield_asm, sizeof(yield_asm),
|
||||||
JDOC("(yield &opt x)\n\n"
|
JDOC("(yield &opt x)\n\n"
|
||||||
"Yield a value to a parent fiber. When a fiber yields, its execution is paused until "
|
"Yield a value to a parent fiber. When a fiber yields, its execution is paused until "
|
||||||
"another thread resumes it. The fiber will then resume, and the last yield call will "
|
"another thread resumes it. The fiber will then resume, and the last yield call will "
|
||||||
"return the value that was passed to resume."));
|
"return the value that was passed to resume."));
|
||||||
janet_quick_asm(env, JANET_FUN_CANCEL,
|
janet_quick_asm(env, JANET_FUN_CANCEL,
|
||||||
"cancel", 2, 2, 2, 2, cancel_asm, sizeof(cancel_asm),
|
"cancel", 2, 2, 2, 2, cancel_asm, sizeof(cancel_asm),
|
||||||
JDOC("(cancel fiber err)\n\n"
|
JDOC("(cancel fiber err)\n\n"
|
||||||
"Resume a fiber but have it immediately raise an error. This lets a programmer unwind a pending fiber. "
|
"Resume a fiber but have it immediately raise an error. This lets a programmer unwind a pending fiber. "
|
||||||
"Returns the same result as resume."));
|
"Returns the same result as resume."));
|
||||||
janet_quick_asm(env, JANET_FUN_RESUME,
|
janet_quick_asm(env, JANET_FUN_RESUME,
|
||||||
"resume", 2, 1, 2, 2, resume_asm, sizeof(resume_asm),
|
"resume", 2, 1, 2, 2, resume_asm, sizeof(resume_asm),
|
||||||
JDOC("(resume fiber &opt x)\n\n"
|
JDOC("(resume fiber &opt x)\n\n"
|
||||||
"Resume a new or suspended fiber and optionally pass in a value to the fiber that "
|
"Resume a new or suspended fiber and optionally pass in a value to the fiber that "
|
||||||
"will be returned to the last yield in the case of a pending fiber, or the argument to "
|
"will be returned to the last yield in the case of a pending fiber, or the argument to "
|
||||||
"the dispatch function in the case of a new fiber. Returns either the return result of "
|
"the dispatch function in the case of a new fiber. Returns either the return result of "
|
||||||
"the fiber's dispatch function, or the value from the next yield call in fiber."));
|
"the fiber's dispatch function, or the value from the next yield call in fiber."));
|
||||||
janet_quick_asm(env, JANET_FUN_IN,
|
janet_quick_asm(env, JANET_FUN_IN,
|
||||||
"in", 3, 2, 3, 4, in_asm, sizeof(in_asm),
|
"in", 3, 2, 3, 4, in_asm, sizeof(in_asm),
|
||||||
JDOC("(in ds key &opt dflt)\n\n"
|
JDOC("(in ds key &opt dflt)\n\n"
|
||||||
"Get value in ds at key, works on associative data structures. Arrays, tuples, tables, structs, "
|
"Get value in ds at key, works on associative data structures. Arrays, tuples, tables, structs, "
|
||||||
"strings, symbols, and buffers are all associative and can be used. Arrays, tuples, strings, buffers, "
|
"strings, symbols, and buffers are all associative and can be used. Arrays, tuples, strings, buffers, "
|
||||||
"and symbols must use integer keys that are in bounds or an error is raised. Structs and tables can "
|
"and symbols must use integer keys that are in bounds or an error is raised. Structs and tables can "
|
||||||
"take any value as a key except nil and will return nil or dflt if not found."));
|
"take any value as a key except nil and will return nil or dflt if not found."));
|
||||||
janet_quick_asm(env, JANET_FUN_GET,
|
janet_quick_asm(env, JANET_FUN_GET,
|
||||||
"get", 3, 2, 3, 4, get_asm, sizeof(in_asm),
|
"get", 3, 2, 3, 4, get_asm, sizeof(in_asm),
|
||||||
JDOC("(get ds key &opt dflt)\n\n"
|
JDOC("(get ds key &opt dflt)\n\n"
|
||||||
"Get the value mapped to key in data structure ds, and return dflt or nil if not found. "
|
"Get the value mapped to key in data structure ds, and return dflt or nil if not found. "
|
||||||
"Similar to in, but will not throw an error if the key is invalid for the data structure "
|
"Similar to in, but will not throw an error if the key is invalid for the data structure "
|
||||||
"unless the data structure is an abstract type. In that case, the abstract type getter may throw "
|
"unless the data structure is an abstract type. In that case, the abstract type getter may throw "
|
||||||
"an error."));
|
"an error."));
|
||||||
janet_quick_asm(env, JANET_FUN_PUT,
|
janet_quick_asm(env, JANET_FUN_PUT,
|
||||||
"put", 3, 3, 3, 3, put_asm, sizeof(put_asm),
|
"put", 3, 3, 3, 3, put_asm, sizeof(put_asm),
|
||||||
JDOC("(put ds key value)\n\n"
|
JDOC("(put ds key value)\n\n"
|
||||||
"Associate a key with a value in any mutable associative data structure. Indexed data structures "
|
"Associate a key with a value in any mutable associative data structure. Indexed data structures "
|
||||||
"(arrays and buffers) only accept non-negative integer keys, and will expand if an out of bounds "
|
"(arrays and buffers) only accept non-negative integer keys, and will expand if an out of bounds "
|
||||||
"value is provided. In an array, extra space will be filled with nils, and in a buffer, extra "
|
"value is provided. In an array, extra space will be filled with nils, and in a buffer, extra "
|
||||||
"space will be filled with 0 bytes. In a table, putting a key that is contained in the table prototype "
|
"space will be filled with 0 bytes. In a table, putting a key that is contained in the table prototype "
|
||||||
"will hide the association defined by the prototype, but will not mutate the prototype table. Putting "
|
"will hide the association defined by the prototype, but will not mutate the prototype table. Putting "
|
||||||
"a value nil into a table will remove the key from the table. Returns the data structure ds."));
|
"a value nil into a table will remove the key from the table. Returns the data structure ds."));
|
||||||
janet_quick_asm(env, JANET_FUN_LENGTH,
|
janet_quick_asm(env, JANET_FUN_LENGTH,
|
||||||
"length", 1, 1, 1, 1, length_asm, sizeof(length_asm),
|
"length", 1, 1, 1, 1, length_asm, sizeof(length_asm),
|
||||||
JDOC("(length ds)\n\n"
|
JDOC("(length ds)\n\n"
|
||||||
"Returns the length or count of a data structure in constant time as an integer. For "
|
"Returns the length or count of a data structure in constant time as an integer. For "
|
||||||
"structs and tables, returns the number of key-value pairs in the data structure."));
|
"structs and tables, returns the number of key-value pairs in the data structure."));
|
||||||
janet_quick_asm(env, JANET_FUN_BNOT,
|
janet_quick_asm(env, JANET_FUN_BNOT,
|
||||||
"bnot", 1, 1, 1, 1, bnot_asm, sizeof(bnot_asm),
|
"bnot", 1, 1, 1, 1, bnot_asm, sizeof(bnot_asm),
|
||||||
JDOC("(bnot x)\n\nReturns the bit-wise inverse of integer x."));
|
JDOC("(bnot x)\n\nReturns the bit-wise inverse of integer x."));
|
||||||
@@ -1243,74 +1235,74 @@ JanetTable *janet_core_env(JanetTable *replacements) {
|
|||||||
/* Variadic ops */
|
/* Variadic ops */
|
||||||
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD,
|
templatize_varop(env, JANET_FUN_ADD, "+", 0, 0, JOP_ADD,
|
||||||
JDOC("(+ & xs)\n\n"
|
JDOC("(+ & xs)\n\n"
|
||||||
"Returns the sum of all xs. xs must be integers or real numbers only. If xs is empty, return 0."));
|
"Returns the sum of all xs. xs must be integers or real numbers only. If xs is empty, return 0."));
|
||||||
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT,
|
templatize_varop(env, JANET_FUN_SUBTRACT, "-", 0, 0, JOP_SUBTRACT,
|
||||||
JDOC("(- & xs)\n\n"
|
JDOC("(- & xs)\n\n"
|
||||||
"Returns the difference of xs. If xs is empty, returns 0. If xs has one element, returns the "
|
"Returns the difference of xs. If xs is empty, returns 0. If xs has one element, returns the "
|
||||||
"negative value of that element. Otherwise, returns the first element in xs minus the sum of "
|
"negative value of that element. Otherwise, returns the first element in xs minus the sum of "
|
||||||
"the rest of the elements."));
|
"the rest of the elements."));
|
||||||
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY,
|
templatize_varop(env, JANET_FUN_MULTIPLY, "*", 1, 1, JOP_MULTIPLY,
|
||||||
JDOC("(* & xs)\n\n"
|
JDOC("(* & xs)\n\n"
|
||||||
"Returns the product of all elements in xs. If xs is empty, returns 1."));
|
"Returns the product of all elements in xs. If xs is empty, returns 1."));
|
||||||
templatize_varop(env, JANET_FUN_DIVIDE, "/", 1, 1, JOP_DIVIDE,
|
templatize_varop(env, JANET_FUN_DIVIDE, "/", 1, 1, JOP_DIVIDE,
|
||||||
JDOC("(/ & xs)\n\n"
|
JDOC("(/ & xs)\n\n"
|
||||||
"Returns the quotient of xs. If xs is empty, returns 1. If xs has one value x, returns "
|
"Returns the quotient of xs. If xs is empty, returns 1. If xs has one value x, returns "
|
||||||
"the reciprocal of x. Otherwise return the first value of xs repeatedly divided by the remaining "
|
"the reciprocal of x. Otherwise return the first value of xs repeatedly divided by the remaining "
|
||||||
"values."));
|
"values."));
|
||||||
templatize_varop(env, JANET_FUN_DIVIDE_FLOOR, "div", 1, 1, JOP_DIVIDE_FLOOR,
|
templatize_varop(env, JANET_FUN_DIVIDE_FLOOR, "div", 1, 1, JOP_DIVIDE_FLOOR,
|
||||||
JDOC("(div & xs)\n\n"
|
JDOC("(div & xs)\n\n"
|
||||||
"Returns the floored division of xs. If xs is empty, returns 1. If xs has one value x, returns "
|
"Returns the floored division of xs. If xs is empty, returns 1. If xs has one value x, returns "
|
||||||
"the reciprocal of x. Otherwise return the first value of xs repeatedly divided by the remaining "
|
"the reciprocal of x. Otherwise return the first value of xs repeatedly divided by the remaining "
|
||||||
"values."));
|
"values."));
|
||||||
templatize_varop(env, JANET_FUN_MODULO, "mod", 0, 1, JOP_MODULO,
|
templatize_varop(env, JANET_FUN_MODULO, "mod", 0, 1, JOP_MODULO,
|
||||||
JDOC("(mod & xs)\n\n"
|
JDOC("(mod & xs)\n\n"
|
||||||
"Returns the result of applying the modulo operator on the first value of xs with each remaining value. "
|
"Returns the result of applying the modulo operator on the first value of xs with each remaining value. "
|
||||||
"`(mod x 0)` is defined to be `x`."));
|
"`(mod x 0)` is defined to be `x`."));
|
||||||
templatize_varop(env, JANET_FUN_REMAINDER, "%", 0, 1, JOP_REMAINDER,
|
templatize_varop(env, JANET_FUN_REMAINDER, "%", 0, 1, JOP_REMAINDER,
|
||||||
JDOC("(% & xs)\n\n"
|
JDOC("(% & xs)\n\n"
|
||||||
"Returns the remainder of dividing the first value of xs by each remaining value."));
|
"Returns the remainder of dividing the first value of xs by each remaining value."));
|
||||||
templatize_varop(env, JANET_FUN_BAND, "band", -1, -1, JOP_BAND,
|
templatize_varop(env, JANET_FUN_BAND, "band", -1, -1, JOP_BAND,
|
||||||
JDOC("(band & xs)\n\n"
|
JDOC("(band & xs)\n\n"
|
||||||
"Returns the bit-wise and of all values in xs. Each x in xs must be an integer."));
|
"Returns the bit-wise and of all values in xs. Each x in xs must be an integer."));
|
||||||
templatize_varop(env, JANET_FUN_BOR, "bor", 0, 0, JOP_BOR,
|
templatize_varop(env, JANET_FUN_BOR, "bor", 0, 0, JOP_BOR,
|
||||||
JDOC("(bor & xs)\n\n"
|
JDOC("(bor & xs)\n\n"
|
||||||
"Returns the bit-wise or of all values in xs. Each x in xs must be an integer."));
|
"Returns the bit-wise or of all values in xs. Each x in xs must be an integer."));
|
||||||
templatize_varop(env, JANET_FUN_BXOR, "bxor", 0, 0, JOP_BXOR,
|
templatize_varop(env, JANET_FUN_BXOR, "bxor", 0, 0, JOP_BXOR,
|
||||||
JDOC("(bxor & xs)\n\n"
|
JDOC("(bxor & xs)\n\n"
|
||||||
"Returns the bit-wise xor of all values in xs. Each in xs must be an integer."));
|
"Returns the bit-wise xor of all values in xs. Each in xs must be an integer."));
|
||||||
templatize_varop(env, JANET_FUN_LSHIFT, "blshift", 1, 1, JOP_SHIFT_LEFT,
|
templatize_varop(env, JANET_FUN_LSHIFT, "blshift", 1, 1, JOP_SHIFT_LEFT,
|
||||||
JDOC("(blshift x & shifts)\n\n"
|
JDOC("(blshift x & shifts)\n\n"
|
||||||
"Returns the value of x bit shifted left by the sum of all values in shifts. x "
|
"Returns the value of x bit shifted left by the sum of all values in shifts. x "
|
||||||
"and each element in shift must be an integer."));
|
"and each element in shift must be an integer."));
|
||||||
templatize_varop(env, JANET_FUN_RSHIFT, "brshift", 1, 1, JOP_SHIFT_RIGHT,
|
templatize_varop(env, JANET_FUN_RSHIFT, "brshift", 1, 1, JOP_SHIFT_RIGHT,
|
||||||
JDOC("(brshift x & shifts)\n\n"
|
JDOC("(brshift x & shifts)\n\n"
|
||||||
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
|
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
|
||||||
"and each element in shift must be an integer."));
|
"and each element in shift must be an integer."));
|
||||||
templatize_varop(env, JANET_FUN_RSHIFTU, "brushift", 1, 1, JOP_SHIFT_RIGHT_UNSIGNED,
|
templatize_varop(env, JANET_FUN_RSHIFTU, "brushift", 1, 1, JOP_SHIFT_RIGHT_UNSIGNED,
|
||||||
JDOC("(brushift x & shifts)\n\n"
|
JDOC("(brushift x & shifts)\n\n"
|
||||||
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
|
"Returns the value of x bit shifted right by the sum of all values in shifts. x "
|
||||||
"and each element in shift must be an integer. The sign of x is not preserved, so "
|
"and each element in shift must be an integer. The sign of x is not preserved, so "
|
||||||
"for positive shifts the return value will always be positive."));
|
"for positive shifts the return value will always be positive."));
|
||||||
|
|
||||||
/* Variadic comparators */
|
/* Variadic comparators */
|
||||||
templatize_comparator(env, JANET_FUN_GT, ">", 0, JOP_GREATER_THAN,
|
templatize_comparator(env, JANET_FUN_GT, ">", 0, JOP_GREATER_THAN,
|
||||||
JDOC("(> & xs)\n\n"
|
JDOC("(> & xs)\n\n"
|
||||||
"Check if xs is in descending order. Returns a boolean."));
|
"Check if xs is in descending order. Returns a boolean."));
|
||||||
templatize_comparator(env, JANET_FUN_LT, "<", 0, JOP_LESS_THAN,
|
templatize_comparator(env, JANET_FUN_LT, "<", 0, JOP_LESS_THAN,
|
||||||
JDOC("(< & xs)\n\n"
|
JDOC("(< & xs)\n\n"
|
||||||
"Check if xs is in ascending order. Returns a boolean."));
|
"Check if xs is in ascending order. Returns a boolean."));
|
||||||
templatize_comparator(env, JANET_FUN_GTE, ">=", 0, JOP_GREATER_THAN_EQUAL,
|
templatize_comparator(env, JANET_FUN_GTE, ">=", 0, JOP_GREATER_THAN_EQUAL,
|
||||||
JDOC("(>= & xs)\n\n"
|
JDOC("(>= & xs)\n\n"
|
||||||
"Check if xs is in non-ascending order. Returns a boolean."));
|
"Check if xs is in non-ascending order. Returns a boolean."));
|
||||||
templatize_comparator(env, JANET_FUN_LTE, "<=", 0, JOP_LESS_THAN_EQUAL,
|
templatize_comparator(env, JANET_FUN_LTE, "<=", 0, JOP_LESS_THAN_EQUAL,
|
||||||
JDOC("(<= & xs)\n\n"
|
JDOC("(<= & xs)\n\n"
|
||||||
"Check if xs is in non-descending order. Returns a boolean."));
|
"Check if xs is in non-descending order. Returns a boolean."));
|
||||||
templatize_comparator(env, JANET_FUN_EQ, "=", 0, JOP_EQUALS,
|
templatize_comparator(env, JANET_FUN_EQ, "=", 0, JOP_EQUALS,
|
||||||
JDOC("(= & xs)\n\n"
|
JDOC("(= & xs)\n\n"
|
||||||
"Check if all values in xs are equal. Returns a boolean."));
|
"Check if all values in xs are equal. Returns a boolean."));
|
||||||
templatize_comparator(env, JANET_FUN_NEQ, "not=", 1, JOP_EQUALS,
|
templatize_comparator(env, JANET_FUN_NEQ, "not=", 1, JOP_EQUALS,
|
||||||
JDOC("(not= & xs)\n\n"
|
JDOC("(not= & xs)\n\n"
|
||||||
"Check if any values in xs are not equal. Returns a boolean."));
|
"Check if any values in xs are not equal. Returns a boolean."));
|
||||||
|
|
||||||
/* Platform detection */
|
/* Platform detection */
|
||||||
janet_def(env, "janet/version", janet_cstringv(JANET_VERSION),
|
janet_def(env, "janet/version", janet_cstringv(JANET_VERSION),
|
||||||
@@ -1319,7 +1311,7 @@ JanetTable *janet_core_env(JanetTable *replacements) {
|
|||||||
JDOC("The build identifier of the running janet program."));
|
JDOC("The build identifier of the running janet program."));
|
||||||
janet_def(env, "janet/config-bits", janet_wrap_integer(JANET_CURRENT_CONFIG_BITS),
|
janet_def(env, "janet/config-bits", janet_wrap_integer(JANET_CURRENT_CONFIG_BITS),
|
||||||
JDOC("The flag set of config options from janetconf.h which is used to check "
|
JDOC("The flag set of config options from janetconf.h which is used to check "
|
||||||
"if native modules are compatible with the host program."));
|
"if native modules are compatible with the host program."));
|
||||||
|
|
||||||
/* Allow references to the environment */
|
/* Allow references to the environment */
|
||||||
janet_def(env, "root-env", janet_wrap_table(env),
|
janet_def(env, "root-env", janet_wrap_table(env),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -32,11 +32,9 @@
|
|||||||
#ifdef JANET_EV
|
#ifdef JANET_EV
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#ifdef JANET_WINDOWS
|
#ifdef JANET_WINDOWS
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <io.h>
|
|
||||||
#else
|
#else
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
@@ -45,6 +43,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <netinet/tcp.h>
|
#include <netinet/tcp.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
@@ -626,18 +625,6 @@ void janet_addtimeout(double sec) {
|
|||||||
add_timeout(to);
|
add_timeout(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set timeout for the current root fiber but resume with nil instead of raising an error */
|
|
||||||
void janet_addtimeout_nil(double sec) {
|
|
||||||
JanetFiber *fiber = janet_vm.root_fiber;
|
|
||||||
JanetTimeout to;
|
|
||||||
to.when = ts_delta(ts_now(), sec);
|
|
||||||
to.fiber = fiber;
|
|
||||||
to.curr_fiber = NULL;
|
|
||||||
to.sched_id = fiber->sched_id;
|
|
||||||
to.is_error = 0;
|
|
||||||
add_timeout(to);
|
|
||||||
}
|
|
||||||
|
|
||||||
void janet_ev_inc_refcount(void) {
|
void janet_ev_inc_refcount(void) {
|
||||||
janet_atomic_inc(&janet_vm.listener_count);
|
janet_atomic_inc(&janet_vm.listener_count);
|
||||||
}
|
}
|
||||||
@@ -3276,64 +3263,6 @@ JANET_CORE_FN(janet_cfun_rwlock_write_release,
|
|||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
static JanetFile *get_file_for_stream(JanetStream *stream) {
|
|
||||||
int32_t flags = 0;
|
|
||||||
char fmt[4] = {0};
|
|
||||||
int index = 0;
|
|
||||||
if (stream->flags & JANET_STREAM_READABLE) {
|
|
||||||
flags |= JANET_FILE_READ;
|
|
||||||
janet_sandbox_assert(JANET_SANDBOX_FS_READ);
|
|
||||||
fmt[index++] = 'r';
|
|
||||||
}
|
|
||||||
if (stream->flags & JANET_STREAM_WRITABLE) {
|
|
||||||
flags |= JANET_FILE_WRITE;
|
|
||||||
janet_sandbox_assert(JANET_SANDBOX_FS_WRITE);
|
|
||||||
int currindex = index;
|
|
||||||
fmt[index++] = (currindex == 0) ? 'w' : '+';
|
|
||||||
}
|
|
||||||
if (index == 0) return NULL;
|
|
||||||
/* duplicate handle when converting stream to file */
|
|
||||||
#ifdef JANET_WINDOWS
|
|
||||||
int htype = 0;
|
|
||||||
if (fmt[0] == 'r' && fmt[1] == '+') {
|
|
||||||
htype = _O_RDWR;
|
|
||||||
} else if (fmt[0] == 'r') {
|
|
||||||
htype = _O_RDONLY;
|
|
||||||
} else if (fmt[0] == 'w') {
|
|
||||||
htype = _O_WRONLY;
|
|
||||||
}
|
|
||||||
int fd = _open_osfhandle((intptr_t) stream->handle, htype);
|
|
||||||
if (fd < 0) return NULL;
|
|
||||||
int fd_dup = _dup(fd);
|
|
||||||
if (fd_dup < 0) return NULL;
|
|
||||||
FILE *f = _fdopen(fd_dup, fmt);
|
|
||||||
if (NULL == f) {
|
|
||||||
_close(fd_dup);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int fd_dup = dup(stream->handle);
|
|
||||||
if (fd_dup < 0) return NULL;
|
|
||||||
FILE *f = fdopen(fd_dup, fmt);
|
|
||||||
if (NULL == f) {
|
|
||||||
close(fd_dup);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return janet_makejfile(f, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
JANET_CORE_FN(janet_cfun_to_file,
|
|
||||||
"(ev/to-file)",
|
|
||||||
"Create core/file copy of the stream. This value can be used "
|
|
||||||
"when blocking IO behavior is needed.") {
|
|
||||||
janet_fixarity(argc, 1);
|
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
|
||||||
JanetFile *iof = get_file_for_stream(stream);
|
|
||||||
if (iof == NULL) janet_panic("cannot make file from stream");
|
|
||||||
return janet_wrap_abstract(iof);
|
|
||||||
}
|
|
||||||
|
|
||||||
JANET_CORE_FN(janet_cfun_ev_all_tasks,
|
JANET_CORE_FN(janet_cfun_ev_all_tasks,
|
||||||
"(ev/all-tasks)",
|
"(ev/all-tasks)",
|
||||||
"Get an array of all active fibers that are being used by the scheduler.") {
|
"Get an array of all active fibers that are being used by the scheduler.") {
|
||||||
@@ -3378,7 +3307,6 @@ void janet_lib_ev(JanetTable *env) {
|
|||||||
JANET_CORE_REG("ev/acquire-wlock", janet_cfun_rwlock_write_lock),
|
JANET_CORE_REG("ev/acquire-wlock", janet_cfun_rwlock_write_lock),
|
||||||
JANET_CORE_REG("ev/release-rlock", janet_cfun_rwlock_read_release),
|
JANET_CORE_REG("ev/release-rlock", janet_cfun_rwlock_read_release),
|
||||||
JANET_CORE_REG("ev/release-wlock", janet_cfun_rwlock_write_release),
|
JANET_CORE_REG("ev/release-wlock", janet_cfun_rwlock_write_release),
|
||||||
JANET_CORE_REG("ev/to-file", janet_cfun_to_file),
|
|
||||||
JANET_CORE_REG("ev/all-tasks", janet_cfun_ev_all_tasks),
|
JANET_CORE_REG("ev/all-tasks", janet_cfun_ev_all_tasks),
|
||||||
JANET_REG_END
|
JANET_REG_END
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -400,7 +400,7 @@ static JanetFFIStruct *build_struct_type(int32_t argc, const Janet *argv) {
|
|||||||
|
|
||||||
JanetFFIStruct *st = janet_abstract(&janet_struct_type,
|
JanetFFIStruct *st = janet_abstract(&janet_struct_type,
|
||||||
sizeof(JanetFFIStruct) + argc * sizeof(JanetFFIStructMember));
|
sizeof(JanetFFIStruct) + argc * sizeof(JanetFFIStructMember));
|
||||||
st->field_count = 0;
|
st->field_count = member_count;
|
||||||
st->size = 0;
|
st->size = 0;
|
||||||
st->align = 1;
|
st->align = 1;
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
@@ -418,7 +418,6 @@ static JanetFFIStruct *build_struct_type(int32_t argc, const Janet *argv) {
|
|||||||
st->fields[i].type = decode_ffi_type(argv[j]);
|
st->fields[i].type = decode_ffi_type(argv[j]);
|
||||||
size_t el_size = type_size(st->fields[i].type);
|
size_t el_size = type_size(st->fields[i].type);
|
||||||
size_t el_align = type_align(st->fields[i].type);
|
size_t el_align = type_align(st->fields[i].type);
|
||||||
if (el_align <= 0) janet_panicf("bad field type %V", argv[j]);
|
|
||||||
if (all_packed || pack_one) {
|
if (all_packed || pack_one) {
|
||||||
if (st->size % el_align != 0) is_aligned = 0;
|
if (st->size % el_align != 0) is_aligned = 0;
|
||||||
st->fields[i].offset = st->size;
|
st->fields[i].offset = st->size;
|
||||||
@@ -434,7 +433,6 @@ static JanetFFIStruct *build_struct_type(int32_t argc, const Janet *argv) {
|
|||||||
st->size += (st->align - 1);
|
st->size += (st->align - 1);
|
||||||
st->size /= st->align;
|
st->size /= st->align;
|
||||||
st->size *= st->align;
|
st->size *= st->align;
|
||||||
st->field_count = member_count;
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ typedef struct {
|
|||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
JanetStream *stream;
|
JanetStream *stream;
|
||||||
#endif
|
#endif
|
||||||
JanetTable *watch_descriptors;
|
JanetTable* watch_descriptors;
|
||||||
JanetChannel *channel;
|
JanetChannel *channel;
|
||||||
uint32_t default_flags;
|
uint32_t default_flags;
|
||||||
int is_watching;
|
int is_watching;
|
||||||
@@ -85,9 +85,9 @@ static uint32_t decode_watch_flags(const Janet *options, int32_t n) {
|
|||||||
}
|
}
|
||||||
JanetKeyword keyw = janet_unwrap_keyword(options[i]);
|
JanetKeyword keyw = janet_unwrap_keyword(options[i]);
|
||||||
const JanetWatchFlagName *result = janet_strbinsearch(watcher_flags_linux,
|
const JanetWatchFlagName *result = janet_strbinsearch(watcher_flags_linux,
|
||||||
sizeof(watcher_flags_linux) / sizeof(JanetWatchFlagName),
|
sizeof(watcher_flags_linux) / sizeof(JanetWatchFlagName),
|
||||||
sizeof(JanetWatchFlagName),
|
sizeof(JanetWatchFlagName),
|
||||||
keyw);
|
keyw);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
janet_panicf("unknown inotify flag %v", options[i]);
|
janet_panicf("unknown inotify flag %v", options[i]);
|
||||||
}
|
}
|
||||||
@@ -154,97 +154,99 @@ static void watcher_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
|
|||||||
janet_schedule(fiber, janet_wrap_nil());
|
janet_schedule(fiber, janet_wrap_nil());
|
||||||
janet_async_end(fiber);
|
janet_async_end(fiber);
|
||||||
break;
|
break;
|
||||||
case JANET_ASYNC_EVENT_ERR: {
|
case JANET_ASYNC_EVENT_ERR:
|
||||||
janet_schedule(fiber, janet_wrap_nil());
|
{
|
||||||
janet_async_end(fiber);
|
janet_schedule(fiber, janet_wrap_nil());
|
||||||
break;
|
|
||||||
}
|
|
||||||
read_more:
|
|
||||||
case JANET_ASYNC_EVENT_HUP:
|
|
||||||
case JANET_ASYNC_EVENT_INIT:
|
|
||||||
case JANET_ASYNC_EVENT_READ: {
|
|
||||||
Janet name = janet_wrap_nil();
|
|
||||||
|
|
||||||
/* Assumption - read will never return partial events *
|
|
||||||
* From documentation:
|
|
||||||
*
|
|
||||||
* The behavior when the buffer given to read(2) is too small to
|
|
||||||
* return information about the next event depends on the kernel
|
|
||||||
* version: before Linux 2.6.21, read(2) returns 0; since Linux
|
|
||||||
* 2.6.21, read(2) fails with the error EINVAL. Specifying a buffer
|
|
||||||
* of size
|
|
||||||
*
|
|
||||||
* sizeof(struct inotify_event) + NAME_MAX + 1
|
|
||||||
*
|
|
||||||
* will be sufficient to read at least one event. */
|
|
||||||
ssize_t nread;
|
|
||||||
do {
|
|
||||||
nread = read(stream->handle, buf, sizeof(buf));
|
|
||||||
} while (nread == -1 && errno == EINTR);
|
|
||||||
|
|
||||||
/* Check for errors - special case errors that can just be waited on to fix */
|
|
||||||
if (nread == -1) {
|
|
||||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
janet_cancel(fiber, janet_ev_lasterr());
|
|
||||||
fiber->ev_state = NULL;
|
|
||||||
janet_async_end(fiber);
|
janet_async_end(fiber);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nread < (ssize_t) sizeof(struct inotify_event)) break;
|
read_more:
|
||||||
|
case JANET_ASYNC_EVENT_HUP:
|
||||||
|
case JANET_ASYNC_EVENT_INIT:
|
||||||
|
case JANET_ASYNC_EVENT_READ:
|
||||||
|
{
|
||||||
|
Janet name = janet_wrap_nil();
|
||||||
|
|
||||||
/* Iterate through all events read from the buffer */
|
/* Assumption - read will never return partial events *
|
||||||
char *cursor = buf;
|
* From documentation:
|
||||||
while (cursor < buf + nread) {
|
*
|
||||||
struct inotify_event inevent;
|
* The behavior when the buffer given to read(2) is too small to
|
||||||
memcpy(&inevent, cursor, sizeof(inevent));
|
* return information about the next event depends on the kernel
|
||||||
cursor += sizeof(inevent);
|
* version: before Linux 2.6.21, read(2) returns 0; since Linux
|
||||||
/* Read path of inevent */
|
* 2.6.21, read(2) fails with the error EINVAL. Specifying a buffer
|
||||||
if (inevent.len) {
|
* of size
|
||||||
name = janet_cstringv(cursor);
|
*
|
||||||
cursor += inevent.len;
|
* sizeof(struct inotify_event) + NAME_MAX + 1
|
||||||
}
|
*
|
||||||
|
* will be sufficient to read at least one event. */
|
||||||
|
ssize_t nread;
|
||||||
|
do {
|
||||||
|
nread = read(stream->handle, buf, sizeof(buf));
|
||||||
|
} while (nread == -1 && errno == EINTR);
|
||||||
|
|
||||||
/* Got an event */
|
/* Check for errors - special case errors that can just be waited on to fix */
|
||||||
Janet path = janet_table_get(watcher->watch_descriptors, janet_wrap_integer(inevent.wd));
|
if (nread == -1) {
|
||||||
JanetKV *event = janet_struct_begin(6);
|
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||||
janet_struct_put(event, janet_ckeywordv("wd"), janet_wrap_integer(inevent.wd));
|
break;
|
||||||
janet_struct_put(event, janet_ckeywordv("wd-path"), path);
|
|
||||||
if (janet_checktype(name, JANET_NIL)) {
|
|
||||||
/* We were watching a file directly, so path is the full path. Split into dirname / basename */
|
|
||||||
JanetString spath = janet_unwrap_string(path);
|
|
||||||
const uint8_t *cursor = spath + janet_string_length(spath);
|
|
||||||
const uint8_t *cursor_end = cursor;
|
|
||||||
while (cursor > spath && cursor[0] != '/') {
|
|
||||||
cursor--;
|
|
||||||
}
|
}
|
||||||
if (cursor == spath) {
|
janet_cancel(fiber, janet_ev_lasterr());
|
||||||
|
fiber->ev_state = NULL;
|
||||||
|
janet_async_end(fiber);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (nread < (ssize_t) sizeof(struct inotify_event)) break;
|
||||||
|
|
||||||
|
/* Iterate through all events read from the buffer */
|
||||||
|
char *cursor = buf;
|
||||||
|
while (cursor < buf + nread) {
|
||||||
|
struct inotify_event inevent;
|
||||||
|
memcpy(&inevent, cursor, sizeof(inevent));
|
||||||
|
cursor += sizeof(inevent);
|
||||||
|
/* Read path of inevent */
|
||||||
|
if (inevent.len) {
|
||||||
|
name = janet_cstringv(cursor);
|
||||||
|
cursor += inevent.len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Got an event */
|
||||||
|
Janet path = janet_table_get(watcher->watch_descriptors, janet_wrap_integer(inevent.wd));
|
||||||
|
JanetKV *event = janet_struct_begin(6);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("wd"), janet_wrap_integer(inevent.wd));
|
||||||
|
janet_struct_put(event, janet_ckeywordv("wd-path"), path);
|
||||||
|
if (janet_checktype(name, JANET_NIL)) {
|
||||||
|
/* We were watching a file directly, so path is the full path. Split into dirname / basename */
|
||||||
|
JanetString spath = janet_unwrap_string(path);
|
||||||
|
const uint8_t *cursor = spath + janet_string_length(spath);
|
||||||
|
const uint8_t *cursor_end = cursor;
|
||||||
|
while (cursor > spath && cursor[0] != '/') {
|
||||||
|
cursor--;
|
||||||
|
}
|
||||||
|
if (cursor == spath) {
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
||||||
|
} else {
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(janet_string(spath, (cursor - spath))));
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), janet_wrap_string(janet_string(cursor + 1, (cursor_end - cursor - 1))));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
||||||
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
||||||
} else {
|
|
||||||
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(janet_string(spath, (cursor - spath))));
|
|
||||||
janet_struct_put(event, janet_ckeywordv("file-name"), janet_wrap_string(janet_string(cursor + 1, (cursor_end - cursor - 1))));
|
|
||||||
}
|
}
|
||||||
} else {
|
janet_struct_put(event, janet_ckeywordv("cookie"), janet_wrap_integer(inevent.cookie));
|
||||||
janet_struct_put(event, janet_ckeywordv("dir-name"), path);
|
Janet etype = janet_ckeywordv("type");
|
||||||
janet_struct_put(event, janet_ckeywordv("file-name"), name);
|
const JanetWatchFlagName *wfn_end = watcher_flags_linux + sizeof(watcher_flags_linux) / sizeof(watcher_flags_linux[0]);
|
||||||
}
|
for (const JanetWatchFlagName *wfn = watcher_flags_linux; wfn < wfn_end; wfn++) {
|
||||||
janet_struct_put(event, janet_ckeywordv("cookie"), janet_wrap_integer(inevent.cookie));
|
if ((inevent.mask & wfn->flag) == wfn->flag) janet_struct_put(event, etype, janet_ckeywordv(wfn->name));
|
||||||
Janet etype = janet_ckeywordv("type");
|
}
|
||||||
const JanetWatchFlagName *wfn_end = watcher_flags_linux + sizeof(watcher_flags_linux) / sizeof(watcher_flags_linux[0]);
|
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
||||||
for (const JanetWatchFlagName *wfn = watcher_flags_linux; wfn < wfn_end; wfn++) {
|
|
||||||
if ((inevent.mask & wfn->flag) == wfn->flag) janet_struct_put(event, etype, janet_ckeywordv(wfn->name));
|
|
||||||
}
|
|
||||||
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
|
||||||
|
|
||||||
janet_channel_give(watcher->channel, eventv);
|
janet_channel_give(watcher->channel, eventv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read some more if possible */
|
||||||
|
goto read_more;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
/* Read some more if possible */
|
|
||||||
goto read_more;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,8 +273,7 @@ static void janet_watcher_unlisten(JanetWatcher *watcher) {
|
|||||||
#define WATCHFLAG_RECURSIVE 0x100000u
|
#define WATCHFLAG_RECURSIVE 0x100000u
|
||||||
|
|
||||||
static const JanetWatchFlagName watcher_flags_windows[] = {
|
static const JanetWatchFlagName watcher_flags_windows[] = {
|
||||||
{
|
{"all",
|
||||||
"all",
|
|
||||||
FILE_NOTIFY_CHANGE_ATTRIBUTES |
|
FILE_NOTIFY_CHANGE_ATTRIBUTES |
|
||||||
FILE_NOTIFY_CHANGE_CREATION |
|
FILE_NOTIFY_CHANGE_CREATION |
|
||||||
FILE_NOTIFY_CHANGE_DIR_NAME |
|
FILE_NOTIFY_CHANGE_DIR_NAME |
|
||||||
@@ -281,8 +282,7 @@ static const JanetWatchFlagName watcher_flags_windows[] = {
|
|||||||
FILE_NOTIFY_CHANGE_LAST_WRITE |
|
FILE_NOTIFY_CHANGE_LAST_WRITE |
|
||||||
FILE_NOTIFY_CHANGE_SECURITY |
|
FILE_NOTIFY_CHANGE_SECURITY |
|
||||||
FILE_NOTIFY_CHANGE_SIZE |
|
FILE_NOTIFY_CHANGE_SIZE |
|
||||||
WATCHFLAG_RECURSIVE
|
WATCHFLAG_RECURSIVE},
|
||||||
},
|
|
||||||
{"attributes", FILE_NOTIFY_CHANGE_ATTRIBUTES},
|
{"attributes", FILE_NOTIFY_CHANGE_ATTRIBUTES},
|
||||||
{"creation", FILE_NOTIFY_CHANGE_CREATION},
|
{"creation", FILE_NOTIFY_CHANGE_CREATION},
|
||||||
{"dir-name", FILE_NOTIFY_CHANGE_DIR_NAME},
|
{"dir-name", FILE_NOTIFY_CHANGE_DIR_NAME},
|
||||||
@@ -302,9 +302,9 @@ static uint32_t decode_watch_flags(const Janet *options, int32_t n) {
|
|||||||
}
|
}
|
||||||
JanetKeyword keyw = janet_unwrap_keyword(options[i]);
|
JanetKeyword keyw = janet_unwrap_keyword(options[i]);
|
||||||
const JanetWatchFlagName *result = janet_strbinsearch(watcher_flags_windows,
|
const JanetWatchFlagName *result = janet_strbinsearch(watcher_flags_windows,
|
||||||
sizeof(watcher_flags_windows) / sizeof(JanetWatchFlagName),
|
sizeof(watcher_flags_windows) / sizeof(JanetWatchFlagName),
|
||||||
sizeof(JanetWatchFlagName),
|
sizeof(JanetWatchFlagName),
|
||||||
keyw);
|
keyw);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
janet_panicf("unknown windows filewatch flag %v", options[i]);
|
janet_panicf("unknown windows filewatch flag %v", options[i]);
|
||||||
}
|
}
|
||||||
@@ -339,19 +339,19 @@ typedef struct {
|
|||||||
|
|
||||||
static void read_dir_changes(OverlappedWatch *ow) {
|
static void read_dir_changes(OverlappedWatch *ow) {
|
||||||
BOOL result = ReadDirectoryChangesW(ow->stream->handle,
|
BOOL result = ReadDirectoryChangesW(ow->stream->handle,
|
||||||
(NotifyChange *) ow->buf,
|
(NotifyChange *) ow->buf,
|
||||||
FILE_INFO_PADDING,
|
FILE_INFO_PADDING,
|
||||||
(ow->flags & WATCHFLAG_RECURSIVE) ? TRUE : FALSE,
|
(ow->flags & WATCHFLAG_RECURSIVE) ? TRUE : FALSE,
|
||||||
ow->flags & ~WATCHFLAG_RECURSIVE,
|
ow->flags & ~WATCHFLAG_RECURSIVE,
|
||||||
NULL,
|
NULL,
|
||||||
(OVERLAPPED *) ow,
|
(OVERLAPPED *) ow,
|
||||||
NULL);
|
NULL);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
janet_panicv(janet_ev_lasterr());
|
janet_panicv(janet_ev_lasterr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *watcher_actions_windows[] = {
|
static const char* watcher_actions_windows[] = {
|
||||||
"unknown",
|
"unknown",
|
||||||
"added",
|
"added",
|
||||||
"removed",
|
"removed",
|
||||||
@@ -382,47 +382,48 @@ static void watcher_callback_read(JanetFiber *fiber, JanetAsyncEvent event) {
|
|||||||
case JANET_ASYNC_EVENT_FAILED:
|
case JANET_ASYNC_EVENT_FAILED:
|
||||||
janet_stream_close(ow->stream);
|
janet_stream_close(ow->stream);
|
||||||
break;
|
break;
|
||||||
case JANET_ASYNC_EVENT_COMPLETE: {
|
case JANET_ASYNC_EVENT_COMPLETE:
|
||||||
if (!watcher->is_watching) {
|
{
|
||||||
janet_stream_close(ow->stream);
|
if (!watcher->is_watching) {
|
||||||
break;
|
janet_stream_close(ow->stream);
|
||||||
}
|
break;
|
||||||
|
|
||||||
NotifyChange *fni = (NotifyChange *) ow->buf;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
/* Got an event */
|
|
||||||
|
|
||||||
/* Extract name */
|
|
||||||
Janet filename;
|
|
||||||
if (fni->FileNameLength) {
|
|
||||||
int32_t nbytes = (int32_t) WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
|
||||||
janet_assert(nbytes, "bad utf8 path");
|
|
||||||
uint8_t *into = janet_string_begin(nbytes);
|
|
||||||
WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(wchar_t), (char *) into, nbytes, NULL, NULL);
|
|
||||||
filename = janet_wrap_string(janet_string_end(into));
|
|
||||||
} else {
|
|
||||||
filename = janet_cstringv("");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JanetKV *event = janet_struct_begin(3);
|
NotifyChange *fni = (NotifyChange *) ow->buf;
|
||||||
janet_struct_put(event, janet_ckeywordv("type"), janet_ckeywordv(watcher_actions_windows[fni->Action]));
|
|
||||||
janet_struct_put(event, janet_ckeywordv("file-name"), filename);
|
|
||||||
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(ow->dir_path));
|
|
||||||
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
|
||||||
|
|
||||||
janet_channel_give(watcher->channel, eventv);
|
while (1) {
|
||||||
|
/* Got an event */
|
||||||
|
|
||||||
/* Next event */
|
/* Extract name */
|
||||||
if (!fni->NextEntryOffset) break;
|
Janet filename;
|
||||||
fni = (NotifyChange *)((char *)fni + fni->NextEntryOffset);
|
if (fni->FileNameLength) {
|
||||||
|
int32_t nbytes = (int32_t) WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(wchar_t), NULL, 0, NULL, NULL);
|
||||||
|
janet_assert(nbytes, "bad utf8 path");
|
||||||
|
uint8_t *into = janet_string_begin(nbytes);
|
||||||
|
WideCharToMultiByte(CP_UTF8, 0, fni->FileName, fni->FileNameLength / sizeof(wchar_t), (char *) into, nbytes, NULL, NULL);
|
||||||
|
filename = janet_wrap_string(janet_string_end(into));
|
||||||
|
} else {
|
||||||
|
filename = janet_cstringv("");
|
||||||
|
}
|
||||||
|
|
||||||
|
JanetKV *event = janet_struct_begin(3);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("type"), janet_ckeywordv(watcher_actions_windows[fni->Action]));
|
||||||
|
janet_struct_put(event, janet_ckeywordv("file-name"), filename);
|
||||||
|
janet_struct_put(event, janet_ckeywordv("dir-name"), janet_wrap_string(ow->dir_path));
|
||||||
|
Janet eventv = janet_wrap_struct(janet_struct_end(event));
|
||||||
|
|
||||||
|
janet_channel_give(watcher->channel, eventv);
|
||||||
|
|
||||||
|
/* Next event */
|
||||||
|
if (!fni->NextEntryOffset) break;
|
||||||
|
fni = (NotifyChange *) ((char *)fni + fni->NextEntryOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make another call to read directory changes */
|
||||||
|
read_dir_changes(ow);
|
||||||
|
janet_async_in_flight(fiber);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
/* Make another call to read directory changes */
|
|
||||||
read_dir_changes(ow);
|
|
||||||
janet_async_in_flight(fiber);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -438,12 +439,12 @@ static void start_listening_ow(OverlappedWatch *ow) {
|
|||||||
|
|
||||||
static void janet_watcher_add(JanetWatcher *watcher, const char *path, uint32_t flags) {
|
static void janet_watcher_add(JanetWatcher *watcher, const char *path, uint32_t flags) {
|
||||||
HANDLE handle = CreateFileA(path,
|
HANDLE handle = CreateFileA(path,
|
||||||
FILE_LIST_DIRECTORY | GENERIC_READ,
|
FILE_LIST_DIRECTORY | GENERIC_READ,
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS,
|
FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS,
|
||||||
NULL);
|
NULL);
|
||||||
if (handle == INVALID_HANDLE_VALUE) {
|
if (handle == INVALID_HANDLE_VALUE) {
|
||||||
janet_panicv(janet_ev_lasterr());
|
janet_panicv(janet_ev_lasterr());
|
||||||
}
|
}
|
||||||
@@ -573,21 +574,20 @@ static const JanetAbstractType janet_filewatch_at = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_make,
|
JANET_CORE_FN(cfun_filewatch_make,
|
||||||
"(filewatch/new channel &opt default-flags)",
|
"(filewatch/new channel &opt default-flags)",
|
||||||
"Create a new filewatcher that will give events to a channel channel. See `filewatch/add` for available flags.\n\n"
|
"Create a new filewatcher that will give events to a channel channel. See `filewatch/add` for available flags.\n\n"
|
||||||
"When an event is triggered by the filewatcher, a struct containing information will be given to channel as with `ev/give`. "
|
"When an event is triggered by the filewatcher, a struct containing information will be given to channel as with `ev/give`. "
|
||||||
"The contents of the channel depend on the OS, but will contain some common keys:\n\n"
|
"The contents of the channel depend on the OS, but will contain some common keys:\n\n"
|
||||||
"* `:type` -- the type of the event that was raised.\n\n"
|
"* `:type` -- the type of the event that was raised.\n\n"
|
||||||
"* `:file-name` -- the base file name of the file that triggered the event.\n\n"
|
"* `:file-name` -- the base file name of the file that triggered the event.\n\n"
|
||||||
"* `:dir-name` -- the directory name of the file that triggered the event.\n\n"
|
"* `:dir-name` -- the directory name of the file that triggered the event.\n\n"
|
||||||
"Events also will contain keys specific to the host OS.\n\n"
|
"Events also will contain keys specific to the host OS.\n\n"
|
||||||
"Windows has no extra properties on events.\n\n"
|
"Windows has no extra properties on events.\n\n"
|
||||||
"Linux has the following extra properties on events:\n\n"
|
"Linux has the following extra properties on events:\n\n"
|
||||||
"* `:wd` -- the integer key returned by `filewatch/add` for the path that triggered this.\n\n"
|
"* `:wd` -- the integer key returned by `filewatch/add` for the path that triggered this.\n\n"
|
||||||
"* `:wd-path` -- the string path for watched directory of file. For files, will be the same as `:file-name`, and for directories, will be the same as `:dir-name`.\n\n"
|
"* `:wd-path` -- the string path for watched directory of file. For files, will be the same as `:file-name`, and for directories, will be the same as `:dir-name`.\n\n"
|
||||||
"* `:cookie` -- a randomized integer used to associate related events, such as :moved-from and :moved-to events.\n\n"
|
"* `:cookie` -- a randomized integer used to associate related events, such as :moved-from and :moved-to events.\n\n"
|
||||||
"") {
|
"") {
|
||||||
janet_sandbox_assert(JANET_SANDBOX_FS_READ);
|
|
||||||
janet_arity(argc, 1, -1);
|
janet_arity(argc, 1, -1);
|
||||||
JanetChannel *channel = janet_getchannel(argv, 0);
|
JanetChannel *channel = janet_getchannel(argv, 0);
|
||||||
JanetWatcher *watcher = janet_abstract(&janet_filewatch_at, sizeof(JanetWatcher));
|
JanetWatcher *watcher = janet_abstract(&janet_filewatch_at, sizeof(JanetWatcher));
|
||||||
@@ -597,44 +597,44 @@ JANET_CORE_FN(cfun_filewatch_make,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_add,
|
JANET_CORE_FN(cfun_filewatch_add,
|
||||||
"(filewatch/add watcher path &opt flags)",
|
"(filewatch/add watcher path &opt flags)",
|
||||||
"Add a path to the watcher. Available flags depend on the current OS, and are as follows:\n\n"
|
"Add a path to the watcher. Available flags depend on the current OS, and are as follows:\n\n"
|
||||||
"Windows/MINGW (flags correspond to FILE_NOTIFY_CHANGE_* flags in win32 documentation):\n\n"
|
"Windows/MINGW (flags correspond to FILE_NOTIFY_CHANGE_* flags in win32 documentation):\n\n"
|
||||||
"* `:all` - trigger an event for all of the below triggers.\n\n"
|
"* `:all` - trigger an event for all of the below triggers.\n\n"
|
||||||
"* `:attributes` - FILE_NOTIFY_CHANGE_ATTRIBUTES\n\n"
|
"* `:attributes` - FILE_NOTIFY_CHANGE_ATTRIBUTES\n\n"
|
||||||
"* `:creation` - FILE_NOTIFY_CHANGE_CREATION\n\n"
|
"* `:creation` - FILE_NOTIFY_CHANGE_CREATION\n\n"
|
||||||
"* `:dir-name` - FILE_NOTIFY_CHANGE_DIR_NAME\n\n"
|
"* `:dir-name` - FILE_NOTIFY_CHANGE_DIR_NAME\n\n"
|
||||||
"* `:last-access` - FILE_NOTIFY_CHANGE_LAST_ACCESS\n\n"
|
"* `:last-access` - FILE_NOTIFY_CHANGE_LAST_ACCESS\n\n"
|
||||||
"* `:last-write` - FILE_NOTIFY_CHANGE_LAST_WRITE\n\n"
|
"* `:last-write` - FILE_NOTIFY_CHANGE_LAST_WRITE\n\n"
|
||||||
"* `:security` - FILE_NOTIFY_CHANGE_SECURITY\n\n"
|
"* `:security` - FILE_NOTIFY_CHANGE_SECURITY\n\n"
|
||||||
"* `:size` - FILE_NOTIFY_CHANGE_SIZE\n\n"
|
"* `:size` - FILE_NOTIFY_CHANGE_SIZE\n\n"
|
||||||
"* `:recursive` - watch subdirectories recursively\n\n"
|
"* `:recursive` - watch subdirectories recursively\n\n"
|
||||||
"Linux (flags correspond to IN_* flags from <sys/inotify.h>):\n\n"
|
"Linux (flags correspond to IN_* flags from <sys/inotify.h>):\n\n"
|
||||||
"* `:access` - IN_ACCESS\n\n"
|
"* `:access` - IN_ACCESS\n\n"
|
||||||
"* `:all` - IN_ALL_EVENTS\n\n"
|
"* `:all` - IN_ALL_EVENTS\n\n"
|
||||||
"* `:attrib` - IN_ATTRIB\n\n"
|
"* `:attrib` - IN_ATTRIB\n\n"
|
||||||
"* `:close-nowrite` - IN_CLOSE_NOWRITE\n\n"
|
"* `:close-nowrite` - IN_CLOSE_NOWRITE\n\n"
|
||||||
"* `:close-write` - IN_CLOSE_WRITE\n\n"
|
"* `:close-write` - IN_CLOSE_WRITE\n\n"
|
||||||
"* `:create` - IN_CREATE\n\n"
|
"* `:create` - IN_CREATE\n\n"
|
||||||
"* `:delete` - IN_DELETE\n\n"
|
"* `:delete` - IN_DELETE\n\n"
|
||||||
"* `:delete-self` - IN_DELETE_SELF\n\n"
|
"* `:delete-self` - IN_DELETE_SELF\n\n"
|
||||||
"* `:ignored` - IN_IGNORED\n\n"
|
"* `:ignored` - IN_IGNORED\n\n"
|
||||||
"* `:modify` - IN_MODIFY\n\n"
|
"* `:modify` - IN_MODIFY\n\n"
|
||||||
"* `:move-self` - IN_MOVE_SELF\n\n"
|
"* `:move-self` - IN_MOVE_SELF\n\n"
|
||||||
"* `:moved-from` - IN_MOVED_FROM\n\n"
|
"* `:moved-from` - IN_MOVED_FROM\n\n"
|
||||||
"* `:moved-to` - IN_MOVED_TO\n\n"
|
"* `:moved-to` - IN_MOVED_TO\n\n"
|
||||||
"* `:open` - IN_OPEN\n\n"
|
"* `:open` - IN_OPEN\n\n"
|
||||||
"* `:q-overflow` - IN_Q_OVERFLOW\n\n"
|
"* `:q-overflow` - IN_Q_OVERFLOW\n\n"
|
||||||
"* `:unmount` - IN_UNMOUNT\n\n\n"
|
"* `:unmount` - IN_UNMOUNT\n\n\n"
|
||||||
"On Windows, events will have the following possible types:\n\n"
|
"On Windows, events will have the following possible types:\n\n"
|
||||||
"* `:unknown`\n\n"
|
"* `:unknown`\n\n"
|
||||||
"* `:added`\n\n"
|
"* `:added`\n\n"
|
||||||
"* `:removed`\n\n"
|
"* `:removed`\n\n"
|
||||||
"* `:modified`\n\n"
|
"* `:modified`\n\n"
|
||||||
"* `:renamed-old`\n\n"
|
"* `:renamed-old`\n\n"
|
||||||
"* `:renamed-new`\n\n"
|
"* `:renamed-new`\n\n"
|
||||||
"On Linux, events will a `:type` corresponding to the possible flags, excluding `:all`.\n"
|
"On Linux, events will a `:type` corresponding to the possible flags, excluding `:all`.\n"
|
||||||
"") {
|
"") {
|
||||||
janet_arity(argc, 2, -1);
|
janet_arity(argc, 2, -1);
|
||||||
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
||||||
const char *path = janet_getcstring(argv, 1);
|
const char *path = janet_getcstring(argv, 1);
|
||||||
@@ -644,8 +644,8 @@ JANET_CORE_FN(cfun_filewatch_add,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_remove,
|
JANET_CORE_FN(cfun_filewatch_remove,
|
||||||
"(filewatch/remove watcher path)",
|
"(filewatch/remove watcher path)",
|
||||||
"Remove a path from the watcher.") {
|
"Remove a path from the watcher.") {
|
||||||
janet_fixarity(argc, 2);
|
janet_fixarity(argc, 2);
|
||||||
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
||||||
const char *path = janet_getcstring(argv, 1);
|
const char *path = janet_getcstring(argv, 1);
|
||||||
@@ -654,8 +654,8 @@ JANET_CORE_FN(cfun_filewatch_remove,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_listen,
|
JANET_CORE_FN(cfun_filewatch_listen,
|
||||||
"(filewatch/listen watcher)",
|
"(filewatch/listen watcher)",
|
||||||
"Listen for changes in the watcher.") {
|
"Listen for changes in the watcher.") {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
||||||
janet_watcher_listen(watcher);
|
janet_watcher_listen(watcher);
|
||||||
@@ -663,8 +663,8 @@ JANET_CORE_FN(cfun_filewatch_listen,
|
|||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_filewatch_unlisten,
|
JANET_CORE_FN(cfun_filewatch_unlisten,
|
||||||
"(filewatch/unlisten watcher)",
|
"(filewatch/unlisten watcher)",
|
||||||
"Stop listening for changes on a given watcher.") {
|
"Stop listening for changes on a given watcher.") {
|
||||||
janet_fixarity(argc, 1);
|
janet_fixarity(argc, 1);
|
||||||
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
JanetWatcher *watcher = janet_getabstract(argv, 0, &janet_filewatch_at);
|
||||||
janet_watcher_unlisten(watcher);
|
janet_watcher_unlisten(watcher);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose & contributors
|
* Copyright (c) 2023 Calvin Rose & contributors
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -31,7 +31,6 @@
|
|||||||
|
|
||||||
#ifndef JANET_WINDOWS
|
#ifndef JANET_WINDOWS
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -165,14 +164,6 @@ JANET_CORE_FN(cfun_io_fopen,
|
|||||||
}
|
}
|
||||||
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
FILE *f = fopen((const char *)fname, (const char *)fmode);
|
||||||
if (f != NULL) {
|
if (f != NULL) {
|
||||||
#ifndef JANET_WINDOWS
|
|
||||||
struct stat st;
|
|
||||||
fstat(fileno(f), &st);
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
|
||||||
fclose(f);
|
|
||||||
janet_panicf("cannot open directory: %s", fname);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
size_t bufsize = janet_optsize(argv, argc, 2, BUFSIZ);
|
size_t bufsize = janet_optsize(argv, argc, 2, BUFSIZ);
|
||||||
if (bufsize != BUFSIZ) {
|
if (bufsize != BUFSIZ) {
|
||||||
int result = setvbuf(f, NULL, bufsize ? _IOFBF : _IONBF, bufsize);
|
int result = setvbuf(f, NULL, bufsize ? _IOFBF : _IONBF, bufsize);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose and contributors.
|
* Copyright (c) 2023 Calvin Rose and contributors.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -829,7 +829,7 @@ JANET_CORE_FN(cfun_stream_accept_loop,
|
|||||||
JANET_CORE_FN(cfun_stream_accept,
|
JANET_CORE_FN(cfun_stream_accept,
|
||||||
"(net/accept stream &opt timeout)",
|
"(net/accept stream &opt timeout)",
|
||||||
"Get the next connection on a server stream. This would usually be called in a loop in a dedicated fiber. "
|
"Get the next connection on a server stream. This would usually be called in a loop in a dedicated fiber. "
|
||||||
"Takes an optional timeout in seconds, after which will raise an error. "
|
"Takes an optional timeout in seconds, after which will return nil. "
|
||||||
"Returns a new duplex stream which represents a connection to the client.") {
|
"Returns a new duplex stream which represents a connection to the client.") {
|
||||||
janet_arity(argc, 1, 2);
|
janet_arity(argc, 1, 2);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
@@ -844,7 +844,7 @@ JANET_CORE_FN(cfun_stream_read,
|
|||||||
"Read up to n bytes from a stream, suspending the current fiber until the bytes are available. "
|
"Read up to n bytes from a stream, suspending the current fiber until the bytes are available. "
|
||||||
"`n` can also be the keyword `:all` to read into the buffer until end of stream. "
|
"`n` can also be the keyword `:all` to read into the buffer until end of stream. "
|
||||||
"If less than n bytes are available (and more than 0), will push those bytes and return early. "
|
"If less than n bytes are available (and more than 0), will push those bytes and return early. "
|
||||||
"Takes an optional timeout in seconds, after which will raise an error. "
|
"Takes an optional timeout in seconds, after which will return nil. "
|
||||||
"Returns a buffer with up to n more bytes in it, or raises an error if the read failed.") {
|
"Returns a buffer with up to n more bytes in it, or raises an error if the read failed.") {
|
||||||
janet_arity(argc, 2, 4);
|
janet_arity(argc, 2, 4);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
@@ -864,7 +864,7 @@ JANET_CORE_FN(cfun_stream_read,
|
|||||||
JANET_CORE_FN(cfun_stream_chunk,
|
JANET_CORE_FN(cfun_stream_chunk,
|
||||||
"(net/chunk stream nbytes &opt buf timeout)",
|
"(net/chunk stream nbytes &opt buf timeout)",
|
||||||
"Same a net/read, but will wait for all n bytes to arrive rather than return early. "
|
"Same a net/read, but will wait for all n bytes to arrive rather than return early. "
|
||||||
"Takes an optional timeout in seconds, after which will raise an error.") {
|
"Takes an optional timeout in seconds, after which will return nil.") {
|
||||||
janet_arity(argc, 2, 4);
|
janet_arity(argc, 2, 4);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
janet_stream_flags(stream, JANET_STREAM_READABLE | JANET_STREAM_SOCKET);
|
janet_stream_flags(stream, JANET_STREAM_READABLE | JANET_STREAM_SOCKET);
|
||||||
@@ -878,7 +878,7 @@ JANET_CORE_FN(cfun_stream_chunk,
|
|||||||
JANET_CORE_FN(cfun_stream_recv_from,
|
JANET_CORE_FN(cfun_stream_recv_from,
|
||||||
"(net/recv-from stream nbytes buf &opt timeout)",
|
"(net/recv-from stream nbytes buf &opt timeout)",
|
||||||
"Receives data from a server stream and puts it into a buffer. Returns the socket-address the "
|
"Receives data from a server stream and puts it into a buffer. Returns the socket-address the "
|
||||||
"packet came from. Takes an optional timeout in seconds, after which will raise an error.") {
|
"packet came from. Takes an optional timeout in seconds, after which will return nil.") {
|
||||||
janet_arity(argc, 3, 4);
|
janet_arity(argc, 3, 4);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
janet_stream_flags(stream, JANET_STREAM_UDPSERVER | JANET_STREAM_SOCKET);
|
janet_stream_flags(stream, JANET_STREAM_UDPSERVER | JANET_STREAM_SOCKET);
|
||||||
@@ -892,7 +892,7 @@ JANET_CORE_FN(cfun_stream_recv_from,
|
|||||||
JANET_CORE_FN(cfun_stream_write,
|
JANET_CORE_FN(cfun_stream_write,
|
||||||
"(net/write stream data &opt timeout)",
|
"(net/write stream data &opt timeout)",
|
||||||
"Write data to a stream, suspending the current fiber until the write "
|
"Write data to a stream, suspending the current fiber until the write "
|
||||||
"completes. Takes an optional timeout in seconds, after which will raise an error. "
|
"completes. Takes an optional timeout in seconds, after which will return nil. "
|
||||||
"Returns nil, or raises an error if the write failed.") {
|
"Returns nil, or raises an error if the write failed.") {
|
||||||
janet_arity(argc, 2, 3);
|
janet_arity(argc, 2, 3);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
@@ -911,7 +911,7 @@ JANET_CORE_FN(cfun_stream_write,
|
|||||||
JANET_CORE_FN(cfun_stream_send_to,
|
JANET_CORE_FN(cfun_stream_send_to,
|
||||||
"(net/send-to stream dest data &opt timeout)",
|
"(net/send-to stream dest data &opt timeout)",
|
||||||
"Writes a datagram to a server stream. dest is a the destination address of the packet. "
|
"Writes a datagram to a server stream. dest is a the destination address of the packet. "
|
||||||
"Takes an optional timeout in seconds, after which will raise an error. "
|
"Takes an optional timeout in seconds, after which will return nil. "
|
||||||
"Returns stream.") {
|
"Returns stream.") {
|
||||||
janet_arity(argc, 3, 4);
|
janet_arity(argc, 3, 4);
|
||||||
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
JanetStream *stream = janet_getabstract(argv, 0, &janet_stream_type);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose and contributors.
|
* Copyright (c) 2023 Calvin Rose and contributors.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -27,10 +27,9 @@
|
|||||||
#include "gc.h"
|
#include "gc.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#ifndef JANET_REDUCED_OS
|
#ifndef JANET_REDUCED_OS
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@@ -175,8 +174,6 @@ JANET_CORE_FN(os_arch,
|
|||||||
"* :riscv64\n\n"
|
"* :riscv64\n\n"
|
||||||
"* :sparc\n\n"
|
"* :sparc\n\n"
|
||||||
"* :wasm\n\n"
|
"* :wasm\n\n"
|
||||||
"* :s390\n\n"
|
|
||||||
"* :s390x\n\n"
|
|
||||||
"* :unknown\n") {
|
"* :unknown\n") {
|
||||||
janet_fixarity(argc, 0);
|
janet_fixarity(argc, 0);
|
||||||
(void) argv;
|
(void) argv;
|
||||||
@@ -203,10 +200,6 @@ JANET_CORE_FN(os_arch,
|
|||||||
return janet_ckeywordv("ppc");
|
return janet_ckeywordv("ppc");
|
||||||
#elif (defined(__ppc64__) || defined(_ARCH_PPC64) || defined(_M_PPC))
|
#elif (defined(__ppc64__) || defined(_ARCH_PPC64) || defined(_M_PPC))
|
||||||
return janet_ckeywordv("ppc64");
|
return janet_ckeywordv("ppc64");
|
||||||
#elif (defined(__s390x__))
|
|
||||||
return janet_ckeywordv("s390x");
|
|
||||||
#elif (defined(__s390__))
|
|
||||||
return janet_ckeywordv("s390");
|
|
||||||
#else
|
#else
|
||||||
return janet_ckeywordv("unknown");
|
return janet_ckeywordv("unknown");
|
||||||
#endif
|
#endif
|
||||||
@@ -252,7 +245,7 @@ JANET_CORE_FN(os_exit,
|
|||||||
}
|
}
|
||||||
janet_deinit();
|
janet_deinit();
|
||||||
if (argc >= 2 && janet_truthy(argv[1])) {
|
if (argc >= 2 && janet_truthy(argv[1])) {
|
||||||
_Exit(status);
|
_exit(status);
|
||||||
} else {
|
} else {
|
||||||
exit(status);
|
exit(status);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -231,7 +231,7 @@ static void delim_error(JanetParser *parser, size_t stack_index, char c, const c
|
|||||||
janet_buffer_push_u8(buffer, '`');
|
janet_buffer_push_u8(buffer, '`');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
janet_formatb(buffer, " opened at line %d, column %d", (int32_t) s->line, (int32_t) s->column);
|
janet_formatb(buffer, " opened at line %d, column %d", s->line, s->column);
|
||||||
}
|
}
|
||||||
parser->error = (const char *) janet_string(buffer->data, buffer->count);
|
parser->error = (const char *) janet_string(buffer->data, buffer->count);
|
||||||
parser->flag |= JANET_PARSER_GENERATED_ERROR;
|
parser->flag |= JANET_PARSER_GENERATED_ERROR;
|
||||||
@@ -363,7 +363,8 @@ static int stringend(JanetParser *p, JanetParseState *state) {
|
|||||||
JanetParseState top = p->states[p->statecount - 1];
|
JanetParseState top = p->states[p->statecount - 1];
|
||||||
int32_t indent_col = (int32_t) top.column - 1;
|
int32_t indent_col = (int32_t) top.column - 1;
|
||||||
uint8_t *r = bufstart, *end = r + buflen;
|
uint8_t *r = bufstart, *end = r + buflen;
|
||||||
/* Unless there are only spaces before EOLs, disable reindenting */
|
/* Check if there are any characters before the start column -
|
||||||
|
* if so, do not reindent. */
|
||||||
int reindent = 1;
|
int reindent = 1;
|
||||||
while (reindent && (r < end)) {
|
while (reindent && (r < end)) {
|
||||||
if (*r++ == '\n') {
|
if (*r++ == '\n') {
|
||||||
@@ -373,36 +374,34 @@ static int stringend(JanetParser *p, JanetParseState *state) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((r + 1) < end && *r == '\r' && *(r + 1) == '\n') reindent = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now reindent if able */
|
/* Now reindent if able to, otherwise just drop leading newline. */
|
||||||
if (reindent) {
|
if (!reindent) {
|
||||||
|
if (buflen > 0 && bufstart[0] == '\n') {
|
||||||
|
buflen--;
|
||||||
|
bufstart++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
uint8_t *w = bufstart;
|
uint8_t *w = bufstart;
|
||||||
r = bufstart;
|
r = bufstart;
|
||||||
while (r < end) {
|
while (r < end) {
|
||||||
if (*r == '\n') {
|
if (*r == '\n') {
|
||||||
*w++ = *r++;
|
if (r == bufstart) {
|
||||||
|
/* Skip leading newline */
|
||||||
|
r++;
|
||||||
|
} else {
|
||||||
|
*w++ = *r++;
|
||||||
|
}
|
||||||
for (int32_t j = 0; (r < end) && (*r != '\n') && (j < indent_col); j++, r++);
|
for (int32_t j = 0; (r < end) && (*r != '\n') && (j < indent_col); j++, r++);
|
||||||
if ((r + 1) < end && *r == '\r' && *(r + 1) == '\n') *w++ = *r++;
|
|
||||||
} else {
|
} else {
|
||||||
*w++ = *r++;
|
*w++ = *r++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buflen = (int32_t)(w - bufstart);
|
buflen = (int32_t)(w - bufstart);
|
||||||
}
|
}
|
||||||
/* Check for leading EOL so we can remove it */
|
/* Check for trailing newline character so we can remove it */
|
||||||
if (buflen > 1 && bufstart[0] == '\r' && bufstart[1] == '\n') { /* Windows EOL */
|
if (buflen > 0 && bufstart[buflen - 1] == '\n') {
|
||||||
buflen = buflen - 2;
|
|
||||||
bufstart = bufstart + 2;
|
|
||||||
} else if (buflen > 0 && bufstart[0] == '\n') { /* Unix EOL */
|
|
||||||
buflen--;
|
|
||||||
bufstart++;
|
|
||||||
}
|
|
||||||
/* Check for trailing EOL so we can remove it */
|
|
||||||
if (buflen > 1 && bufstart[buflen - 2] == '\r' && bufstart[buflen - 1] == '\n') { /* Windows EOL */
|
|
||||||
buflen = buflen - 2;
|
|
||||||
} else if (buflen > 0 && bufstart[buflen - 1] == '\n') { /* Unix EOL */
|
|
||||||
buflen--;
|
buflen--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -465,16 +465,6 @@ tail:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RULE_ONLY_TAGS: {
|
|
||||||
CapState cs = cap_save(s);
|
|
||||||
down1(s);
|
|
||||||
const uint8_t *result = peg_rule(s, s->bytecode + rule[1], text);
|
|
||||||
up1(s);
|
|
||||||
if (!result) return NULL;
|
|
||||||
cap_load_keept(s, cs);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RULE_GROUP: {
|
case RULE_GROUP: {
|
||||||
uint32_t tag = rule[2];
|
uint32_t tag = rule[2];
|
||||||
int oldmode = s->mode;
|
int oldmode = s->mode;
|
||||||
@@ -496,30 +486,6 @@ tail:
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
case RULE_NTH: {
|
|
||||||
uint32_t nth = rule[1];
|
|
||||||
if (nth > INT32_MAX) nth = INT32_MAX;
|
|
||||||
uint32_t tag = rule[3];
|
|
||||||
int oldmode = s->mode;
|
|
||||||
CapState cs = cap_save(s);
|
|
||||||
s->mode = PEG_MODE_NORMAL;
|
|
||||||
down1(s);
|
|
||||||
const uint8_t *result = peg_rule(s, s->bytecode + rule[2], text);
|
|
||||||
up1(s);
|
|
||||||
s->mode = oldmode;
|
|
||||||
if (!result) return NULL;
|
|
||||||
int32_t num_sub_captures = s->captures->count - cs.cap;
|
|
||||||
Janet cap;
|
|
||||||
if (num_sub_captures > (int32_t) nth) {
|
|
||||||
cap = s->captures->data[cs.cap + nth];
|
|
||||||
} else {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
cap_load_keept(s, cs);
|
|
||||||
pushcap(s, cap, tag);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
case RULE_SUB: {
|
case RULE_SUB: {
|
||||||
const uint8_t *text_start = text;
|
const uint8_t *text_start = text;
|
||||||
const uint32_t *rule_window = s->bytecode + rule[1];
|
const uint32_t *rule_window = s->bytecode + rule[1];
|
||||||
@@ -1095,9 +1061,6 @@ static void spec_thru(Builder *b, int32_t argc, const Janet *argv) {
|
|||||||
static void spec_drop(Builder *b, int32_t argc, const Janet *argv) {
|
static void spec_drop(Builder *b, int32_t argc, const Janet *argv) {
|
||||||
spec_onerule(b, argc, argv, RULE_DROP);
|
spec_onerule(b, argc, argv, RULE_DROP);
|
||||||
}
|
}
|
||||||
static void spec_only_tags(Builder *b, int32_t argc, const Janet *argv) {
|
|
||||||
spec_onerule(b, argc, argv, RULE_ONLY_TAGS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rule of the form [rule, tag] */
|
/* Rule of the form [rule, tag] */
|
||||||
static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) {
|
static void spec_cap1(Builder *b, int32_t argc, const Janet *argv, uint32_t op) {
|
||||||
@@ -1121,15 +1084,6 @@ static void spec_unref(Builder *b, int32_t argc, const Janet *argv) {
|
|||||||
spec_cap1(b, argc, argv, RULE_UNREF);
|
spec_cap1(b, argc, argv, RULE_UNREF);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spec_nth(Builder *b, int32_t argc, const Janet *argv) {
|
|
||||||
peg_arity(b, argc, 2, 3);
|
|
||||||
Reserve r = reserve(b, 4);
|
|
||||||
uint32_t nth = peg_getnat(b, argv[0]);
|
|
||||||
uint32_t rule = peg_compile1(b, argv[1]);
|
|
||||||
uint32_t tag = (argc == 3) ? emit_tag(b, argv[2]) : 0;
|
|
||||||
emit_3(r, RULE_NTH, nth, rule, tag);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spec_capture_number(Builder *b, int32_t argc, const Janet *argv) {
|
static void spec_capture_number(Builder *b, int32_t argc, const Janet *argv) {
|
||||||
peg_arity(b, argc, 1, 3);
|
peg_arity(b, argc, 1, 3);
|
||||||
Reserve r = reserve(b, 4);
|
Reserve r = reserve(b, 4);
|
||||||
@@ -1308,9 +1262,7 @@ static const SpecialPair peg_specials[] = {
|
|||||||
{"line", spec_line},
|
{"line", spec_line},
|
||||||
{"look", spec_look},
|
{"look", spec_look},
|
||||||
{"not", spec_not},
|
{"not", spec_not},
|
||||||
{"nth", spec_nth},
|
|
||||||
{"number", spec_capture_number},
|
{"number", spec_capture_number},
|
||||||
{"only-tags", spec_only_tags},
|
|
||||||
{"opt", spec_opt},
|
{"opt", spec_opt},
|
||||||
{"position", spec_position},
|
{"position", spec_position},
|
||||||
{"quote", spec_capture},
|
{"quote", spec_capture},
|
||||||
@@ -1667,7 +1619,6 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
|
|||||||
break;
|
break;
|
||||||
case RULE_ERROR:
|
case RULE_ERROR:
|
||||||
case RULE_DROP:
|
case RULE_DROP:
|
||||||
case RULE_ONLY_TAGS:
|
|
||||||
case RULE_NOT:
|
case RULE_NOT:
|
||||||
case RULE_TO:
|
case RULE_TO:
|
||||||
case RULE_THRU:
|
case RULE_THRU:
|
||||||
@@ -1681,12 +1632,6 @@ static void *peg_unmarshal(JanetMarshalContext *ctx) {
|
|||||||
if (rule[1] > JANET_MAX_READINT_WIDTH) goto bad;
|
if (rule[1] > JANET_MAX_READINT_WIDTH) goto bad;
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
case RULE_NTH:
|
|
||||||
/* [nth, rule, tag] */
|
|
||||||
if (rule[2] >= blen) goto bad;
|
|
||||||
op_flags[rule[2]] |= 0x01;
|
|
||||||
i += 4;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -100,7 +100,6 @@ struct JanetVM {
|
|||||||
* return point for panics. */
|
* return point for panics. */
|
||||||
jmp_buf *signal_buf;
|
jmp_buf *signal_buf;
|
||||||
Janet *return_reg;
|
Janet *return_reg;
|
||||||
int coerce_error;
|
|
||||||
|
|
||||||
/* The global registry for c functions. Used to store meta-data
|
/* The global registry for c functions. Used to store meta-data
|
||||||
* along with otherwise bare c function pointers. */
|
* along with otherwise bare c function pointers. */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -71,10 +71,10 @@ int janet_string_compare(const uint8_t *lhs, const uint8_t *rhs) {
|
|||||||
int janet_string_equalconst(const uint8_t *lhs, const uint8_t *rhs, int32_t rlen, int32_t rhash) {
|
int janet_string_equalconst(const uint8_t *lhs, const uint8_t *rhs, int32_t rlen, int32_t rhash) {
|
||||||
int32_t lhash = janet_string_hash(lhs);
|
int32_t lhash = janet_string_hash(lhs);
|
||||||
int32_t llen = janet_string_length(lhs);
|
int32_t llen = janet_string_length(lhs);
|
||||||
if (lhash != rhash || llen != rlen)
|
|
||||||
return 0;
|
|
||||||
if (lhs == rhs)
|
if (lhs == rhs)
|
||||||
return 1;
|
return 1;
|
||||||
|
if (lhash != rhash || llen != rlen)
|
||||||
|
return 0;
|
||||||
return !memcmp(lhs, rhs, rlen);
|
return !memcmp(lhs, rhs, rlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -294,16 +294,6 @@ JANET_CORE_FN(cfun_struct_to_table,
|
|||||||
return janet_wrap_table(tab);
|
return janet_wrap_table(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
JANET_CORE_FN(cfun_struct_rawget,
|
|
||||||
"(struct/rawget st key)",
|
|
||||||
"Gets a value from a struct `st` without looking at the prototype struct. "
|
|
||||||
"If `st` does not contain the key directly, the function will return "
|
|
||||||
"nil without checking the prototype. Returns the value in the struct.") {
|
|
||||||
janet_fixarity(argc, 2);
|
|
||||||
JanetStruct st = janet_getstruct(argv, 0);
|
|
||||||
return janet_struct_rawget(st, argv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load the struct module */
|
/* Load the struct module */
|
||||||
void janet_lib_struct(JanetTable *env) {
|
void janet_lib_struct(JanetTable *env) {
|
||||||
JanetRegExt struct_cfuns[] = {
|
JanetRegExt struct_cfuns[] = {
|
||||||
@@ -311,7 +301,6 @@ void janet_lib_struct(JanetTable *env) {
|
|||||||
JANET_CORE_REG("struct/getproto", cfun_struct_getproto),
|
JANET_CORE_REG("struct/getproto", cfun_struct_getproto),
|
||||||
JANET_CORE_REG("struct/proto-flatten", cfun_struct_flatten),
|
JANET_CORE_REG("struct/proto-flatten", cfun_struct_flatten),
|
||||||
JANET_CORE_REG("struct/to-table", cfun_struct_to_table),
|
JANET_CORE_REG("struct/to-table", cfun_struct_to_table),
|
||||||
JANET_CORE_REG("struct/rawget", cfun_struct_rawget),
|
|
||||||
JANET_REG_END
|
JANET_REG_END
|
||||||
};
|
};
|
||||||
janet_core_cfuns_ext(env, NULL, struct_cfuns);
|
janet_core_cfuns_ext(env, NULL, struct_cfuns);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -79,7 +79,6 @@ const char *const janet_type_names[16] = {
|
|||||||
"pointer"
|
"pointer"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Docstring for signal lists these */
|
|
||||||
const char *const janet_signal_names[14] = {
|
const char *const janet_signal_names[14] = {
|
||||||
"ok",
|
"ok",
|
||||||
"error",
|
"error",
|
||||||
@@ -97,7 +96,6 @@ const char *const janet_signal_names[14] = {
|
|||||||
"await"
|
"await"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Docstring for fiber/status lists these */
|
|
||||||
const char *const janet_status_names[16] = {
|
const char *const janet_status_names[16] = {
|
||||||
"dead",
|
"dead",
|
||||||
"error",
|
"error",
|
||||||
@@ -117,20 +115,14 @@ const char *const janet_status_names[16] = {
|
|||||||
"alive"
|
"alive"
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t janet_hash_mix(uint32_t input, uint32_t more) {
|
|
||||||
uint32_t mix1 = (more + 0x9e3779b9 + (input << 6) + (input >> 2));
|
|
||||||
return input ^ (0x9e3779b9 + (mix1 << 6) + (mix1 >> 2));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef JANET_PRF
|
#ifndef JANET_PRF
|
||||||
|
|
||||||
int32_t janet_string_calchash(const uint8_t *str, int32_t len) {
|
int32_t janet_string_calchash(const uint8_t *str, int32_t len) {
|
||||||
if (NULL == str || len == 0) return 5381;
|
if (NULL == str) return 5381;
|
||||||
const uint8_t *end = str + len;
|
const uint8_t *end = str + len;
|
||||||
uint32_t hash = 5381;
|
uint32_t hash = 5381;
|
||||||
while (str < end)
|
while (str < end)
|
||||||
hash = (hash << 5) + hash + *str++;
|
hash = (hash << 5) + hash + *str++;
|
||||||
hash = janet_hash_mix(hash, (uint32_t) len);
|
|
||||||
return (int32_t) hash;
|
return (int32_t) hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +238,11 @@ int32_t janet_string_calchash(const uint8_t *str, int32_t len) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint32_t janet_hash_mix(uint32_t input, uint32_t more) {
|
||||||
|
uint32_t mix1 = (more + 0x9e3779b9 + (input << 6) + (input >> 2));
|
||||||
|
return input ^ (0x9e3779b9 + (mix1 << 6) + (mix1 >> 2));
|
||||||
|
}
|
||||||
|
|
||||||
/* Computes hash of an array of values */
|
/* Computes hash of an array of values */
|
||||||
int32_t janet_array_calchash(const Janet *array, int32_t len) {
|
int32_t janet_array_calchash(const Janet *array, int32_t len) {
|
||||||
const Janet *end = array + len;
|
const Janet *end = array + len;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -1373,10 +1373,7 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
|
|||||||
|
|
||||||
/* Run vm */
|
/* Run vm */
|
||||||
janet_vm.fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL | JANET_FIBER_RESUME_NO_SKIP;
|
janet_vm.fiber->flags |= JANET_FIBER_RESUME_NO_USEVAL | JANET_FIBER_RESUME_NO_SKIP;
|
||||||
int old_coerce_error = janet_vm.coerce_error;
|
|
||||||
janet_vm.coerce_error = 1;
|
|
||||||
JanetSignal signal = run_vm(janet_vm.fiber, janet_wrap_nil());
|
JanetSignal signal = run_vm(janet_vm.fiber, janet_wrap_nil());
|
||||||
janet_vm.coerce_error = old_coerce_error;
|
|
||||||
|
|
||||||
/* Teardown */
|
/* Teardown */
|
||||||
janet_vm.stackn = oldn;
|
janet_vm.stackn = oldn;
|
||||||
@@ -1387,10 +1384,6 @@ Janet janet_call(JanetFunction *fun, int32_t argc, const Janet *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (signal != JANET_SIGNAL_OK) {
|
if (signal != JANET_SIGNAL_OK) {
|
||||||
/* Should match logic in janet_signalv */
|
|
||||||
if (signal != JANET_SIGNAL_ERROR) {
|
|
||||||
*janet_vm.return_reg = janet_wrap_string(janet_formatc("%v coerced from %s to error", *janet_vm.return_reg, janet_signal_names[signal]));
|
|
||||||
}
|
|
||||||
janet_panicv(*janet_vm.return_reg);
|
janet_panicv(*janet_vm.return_reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1437,10 +1430,8 @@ void janet_try_init(JanetTryState *state) {
|
|||||||
state->vm_fiber = janet_vm.fiber;
|
state->vm_fiber = janet_vm.fiber;
|
||||||
state->vm_jmp_buf = janet_vm.signal_buf;
|
state->vm_jmp_buf = janet_vm.signal_buf;
|
||||||
state->vm_return_reg = janet_vm.return_reg;
|
state->vm_return_reg = janet_vm.return_reg;
|
||||||
state->coerce_error = janet_vm.coerce_error;
|
|
||||||
janet_vm.return_reg = &(state->payload);
|
janet_vm.return_reg = &(state->payload);
|
||||||
janet_vm.signal_buf = &(state->buf);
|
janet_vm.signal_buf = &(state->buf);
|
||||||
janet_vm.coerce_error = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void janet_restore(JanetTryState *state) {
|
void janet_restore(JanetTryState *state) {
|
||||||
@@ -1449,7 +1440,6 @@ void janet_restore(JanetTryState *state) {
|
|||||||
janet_vm.fiber = state->vm_fiber;
|
janet_vm.fiber = state->vm_fiber;
|
||||||
janet_vm.signal_buf = state->vm_jmp_buf;
|
janet_vm.signal_buf = state->vm_jmp_buf;
|
||||||
janet_vm.return_reg = state->vm_return_reg;
|
janet_vm.return_reg = state->vm_return_reg;
|
||||||
janet_vm.coerce_error = state->coerce_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *out) {
|
static JanetSignal janet_continue_no_check(JanetFiber *fiber, Janet in, Janet *out) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
@@ -1261,7 +1261,6 @@ typedef struct {
|
|||||||
/* new state */
|
/* new state */
|
||||||
jmp_buf buf;
|
jmp_buf buf;
|
||||||
Janet payload;
|
Janet payload;
|
||||||
int coerce_error;
|
|
||||||
} JanetTryState;
|
} JanetTryState;
|
||||||
|
|
||||||
/***** END SECTION TYPES *****/
|
/***** END SECTION TYPES *****/
|
||||||
@@ -1443,7 +1442,6 @@ JANET_NO_RETURN JANET_API void janet_sleep_await(double sec);
|
|||||||
/* For use inside listeners - adds a timeout to the current fiber, such that
|
/* For use inside listeners - adds a timeout to the current fiber, such that
|
||||||
* it will be resumed after sec seconds if no other event schedules the current fiber. */
|
* it will be resumed after sec seconds if no other event schedules the current fiber. */
|
||||||
JANET_API void janet_addtimeout(double sec);
|
JANET_API void janet_addtimeout(double sec);
|
||||||
JANET_API void janet_addtimeout_nil(double sec);
|
|
||||||
JANET_API void janet_ev_inc_refcount(void);
|
JANET_API void janet_ev_inc_refcount(void);
|
||||||
JANET_API void janet_ev_dec_refcount(void);
|
JANET_API void janet_ev_dec_refcount(void);
|
||||||
|
|
||||||
@@ -2182,9 +2180,7 @@ typedef enum {
|
|||||||
RULE_UNREF, /* [rule, tag] */
|
RULE_UNREF, /* [rule, tag] */
|
||||||
RULE_CAPTURE_NUM, /* [rule, tag] */
|
RULE_CAPTURE_NUM, /* [rule, tag] */
|
||||||
RULE_SUB, /* [rule, rule] */
|
RULE_SUB, /* [rule, rule] */
|
||||||
RULE_SPLIT, /* [rule, rule] */
|
RULE_SPLIT /* [rule, rule] */
|
||||||
RULE_NTH, /* [nth, rule, tag] */
|
|
||||||
RULE_ONLY_TAGS, /* [rule] */
|
|
||||||
} JanetPegOpcod;
|
} JanetPegOpcod;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
@@ -986,23 +986,4 @@
|
|||||||
(assert (deep= (get (dyn 'a) :source-form) source))
|
(assert (deep= (get (dyn 'a) :source-form) source))
|
||||||
(setdyn *debug* nil)
|
(setdyn *debug* nil)
|
||||||
|
|
||||||
# issue #1516
|
|
||||||
(assert-error "assertf 1 argument" (macex '(assertf true)))
|
|
||||||
(assert (assertf true "fun message") "assertf 2 arguments")
|
|
||||||
(assert (assertf true "%s message" "mystery") "assertf 3 arguments")
|
|
||||||
(assert (assertf (not nil) "%s message" "ordinary") "assertf not nil")
|
|
||||||
(assert-error "assertf error 2" (assertf false "fun message"))
|
|
||||||
(assert-error "assertf error 3" (assertf false "%s message" "mystery"))
|
|
||||||
(assert-error "assertf error 4" (assertf nil "%s %s" "alice" "bob"))
|
|
||||||
|
|
||||||
# issue #1535
|
|
||||||
(loop [i :range [1 1000]]
|
|
||||||
(assert (deep-not= @{:key1 "value1" @"key" "value2"}
|
|
||||||
@{:key1 "value1" @"key" "value2"}) "deep= mutable keys"))
|
|
||||||
(assert (deep-not= {"abc" 123} {@"abc" 123}) "deep= mutable keys vs immutable key")
|
|
||||||
(assert (deep-not= {@"" 1 @"" 2 @"" 3} {@"" 1 @"" 2 @"" 3}) "deep= duplicate mutable keys")
|
|
||||||
(def k1 @"")
|
|
||||||
(def k2 @"")
|
|
||||||
(assert (deep= {k1 1 k2 2} {k1 1 k2 2}) "deep= duplicate mutable keys 2")
|
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|||||||
@@ -117,11 +117,6 @@
|
|||||||
(assert (= 0 (length (bundle/list))) "bundles are listed correctly 7")
|
(assert (= 0 (length (bundle/list))) "bundles are listed correctly 7")
|
||||||
(assert (= 0 (length (bundle/topolist))) "bundles are listed correctly 8")
|
(assert (= 0 (length (bundle/topolist))) "bundles are listed correctly 8")
|
||||||
|
|
||||||
# Try installing a bundle that fails check
|
|
||||||
(assert-error "bad test" (bundle/install "./examples/sample-bad-bundle" :check true))
|
|
||||||
(assert (= 0 (length (bundle/list))) "check failure 0")
|
|
||||||
(assert (= 0 (length (bundle/topolist))) "check failure 1")
|
|
||||||
|
|
||||||
(rmrf syspath)
|
(rmrf syspath)
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|||||||
@@ -418,15 +418,9 @@
|
|||||||
(assert (= result text) (string/format "expected %v, got %v" text result)))
|
(assert (= result text) (string/format "expected %v, got %v" text result)))
|
||||||
|
|
||||||
# Now do our telnet chat
|
# Now do our telnet chat
|
||||||
(def bob (net/connect test-host test-port :stream))
|
(def bob (net/connect test-host test-port))
|
||||||
(expect-read bob "Whats your name?\n")
|
(expect-read bob "Whats your name?\n")
|
||||||
(if (= :mingw (os/which))
|
(net/write bob "bob")
|
||||||
(net/write bob "bob")
|
|
||||||
(do
|
|
||||||
(def fbob (ev/to-file bob))
|
|
||||||
(file/write fbob "bob")
|
|
||||||
(file/flush fbob)
|
|
||||||
(:close fbob)))
|
|
||||||
(expect-read bob "Welcome bob\n")
|
(expect-read bob "Welcome bob\n")
|
||||||
(def alice (net/connect test-host test-port))
|
(def alice (net/connect test-host test-port))
|
||||||
(expect-read alice "Whats your name?\n")
|
(expect-read alice "Whats your name?\n")
|
||||||
@@ -471,13 +465,4 @@
|
|||||||
# Close chat server
|
# Close chat server
|
||||||
(:close chat-server)
|
(:close chat-server)
|
||||||
|
|
||||||
# Issue #1531
|
|
||||||
(def c (ev/chan 0))
|
|
||||||
(ev/spawn (while (def x (ev/take c))))
|
|
||||||
(defn print-to-chan [x] (ev/give c x))
|
|
||||||
(assert-error "coerce await inside janet_call to error"
|
|
||||||
(with-dyns [*out* print-to-chan]
|
|
||||||
(pp :foo)))
|
|
||||||
(ev/chan-close c)
|
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|||||||
@@ -52,7 +52,5 @@
|
|||||||
(assert (= 26 (ffi/size [:char :pack :int @[:char 21]]))
|
(assert (= 26 (ffi/size [:char :pack :int @[:char 21]]))
|
||||||
"array struct size"))
|
"array struct size"))
|
||||||
|
|
||||||
(compwhen has-ffi
|
|
||||||
(assert-error "bad struct issue #1512" (ffi/struct :void)))
|
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02
|
|||||||
(assert (= 1 (length a)) "array/weak marsh 4")
|
(assert (= 1 (length a)) "array/weak marsh 4")
|
||||||
(assert (= nil (get a 0)) "array/weak marsh 5")
|
(assert (= nil (get a 0)) "array/weak marsh 5")
|
||||||
(assert (= nil (get aclone 0)) "array/weak marsh 6")
|
(assert (= nil (get aclone 0)) "array/weak marsh 6")
|
||||||
(assert (deep= (freeze a) (freeze aclone)) "array/weak marsh 7")
|
(assert (deep= a aclone) "array/weak marsh 7")
|
||||||
|
|
||||||
# table weak keys and values
|
# table weak keys and values
|
||||||
(def t (table/weak 1))
|
(def t (table/weak 1))
|
||||||
@@ -196,7 +196,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02
|
|||||||
(gccollect)
|
(gccollect)
|
||||||
(assert (= 1 (length tclone)) "table/weak-keys marsh 3")
|
(assert (= 1 (length tclone)) "table/weak-keys marsh 3")
|
||||||
(assert (= 1 (length t)) "table/weak-keys marsh 4")
|
(assert (= 1 (length t)) "table/weak-keys marsh 4")
|
||||||
(assert (deep= (freeze t) (freeze tclone)) "table/weak-keys marsh 5")
|
(assert (deep= t tclone) "table/weak-keys marsh 5")
|
||||||
|
|
||||||
# table weak values
|
# table weak values
|
||||||
(def t (table/weak-values 1))
|
(def t (table/weak-values 1))
|
||||||
@@ -207,7 +207,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02
|
|||||||
(assert (= 2 (length tclone)) "table/weak-values marsh 2")
|
(assert (= 2 (length tclone)) "table/weak-values marsh 2")
|
||||||
(gccollect)
|
(gccollect)
|
||||||
(assert (= 1 (length t)) "table/weak-value marsh 3")
|
(assert (= 1 (length t)) "table/weak-value marsh 3")
|
||||||
(assert (deep= (freeze t) (freeze tclone)) "table/weak-values marsh 4")
|
(assert (deep= t tclone) "table/weak-values marsh 4")
|
||||||
|
|
||||||
# tables with prototypes
|
# tables with prototypes
|
||||||
(def t (table/weak-values 1))
|
(def t (table/weak-values 1))
|
||||||
@@ -219,7 +219,7 @@ neldb\0\0\0\xD8\x05printG\x01\0\xDE\xDE\xDE'\x03\0marshal_tes/\x02
|
|||||||
(assert (= 2 (length tclone)) "marsh weak tables with prototypes 2")
|
(assert (= 2 (length tclone)) "marsh weak tables with prototypes 2")
|
||||||
(gccollect)
|
(gccollect)
|
||||||
(assert (= 1 (length t)) "marsh weak tables with prototypes 3")
|
(assert (= 1 (length t)) "marsh weak tables with prototypes 3")
|
||||||
(assert (deep= (freeze t) (freeze tclone)) "marsh weak tables with prototypes 4")
|
(assert (deep= t tclone) "marsh weak tables with prototypes 4")
|
||||||
(assert (deep= (getproto t) (getproto tclone)) "marsh weak tables with prototypes 5")
|
(assert (deep= (getproto t) (getproto tclone)) "marsh weak tables with prototypes 5")
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|||||||
@@ -57,8 +57,6 @@
|
|||||||
(for i (+ index 1) (+ index indent 1)
|
(for i (+ index 1) (+ index indent 1)
|
||||||
(case (get text i)
|
(case (get text i)
|
||||||
nil (break)
|
nil (break)
|
||||||
(chr "\r") (if-not (= (chr "\n") (get text (inc i)))
|
|
||||||
(set rewrite false))
|
|
||||||
(chr "\n") (break)
|
(chr "\n") (break)
|
||||||
(chr " ") nil
|
(chr " ") nil
|
||||||
(set rewrite false))))
|
(set rewrite false))))
|
||||||
@@ -66,17 +64,12 @@
|
|||||||
# Only re-indent if no dedented characters.
|
# Only re-indent if no dedented characters.
|
||||||
(def str
|
(def str
|
||||||
(if rewrite
|
(if rewrite
|
||||||
(peg/replace-all ~(* '(* (? "\r") "\n") (between 0 ,indent " "))
|
(peg/replace-all ~(* "\n" (between 0 ,indent " ")) "\n" text)
|
||||||
(fn [mtch eol] eol) text)
|
|
||||||
text))
|
text))
|
||||||
|
|
||||||
(def first-eol (cond
|
(def first-nl (= (chr "\n") (first str)))
|
||||||
(string/has-prefix? "\r\n" str) :crlf
|
(def last-nl (= (chr "\n") (last str)))
|
||||||
(string/has-prefix? "\n" str) :lf))
|
(string/slice str (if first-nl 1 0) (if last-nl -2)))
|
||||||
(def last-eol (cond
|
|
||||||
(string/has-suffix? "\r\n" str) :crlf
|
|
||||||
(string/has-suffix? "\n" str) :lf))
|
|
||||||
(string/slice str (case first-eol :crlf 2 :lf 1 0) (case last-eol :crlf -3 :lf -2)))
|
|
||||||
|
|
||||||
(defn reindent-reference
|
(defn reindent-reference
|
||||||
"Same as reindent but use parser functionality. Useful for
|
"Same as reindent but use parser functionality. Useful for
|
||||||
@@ -96,10 +89,8 @@
|
|||||||
(let [a (reindent text indent)
|
(let [a (reindent text indent)
|
||||||
b (reindent-reference text indent)]
|
b (reindent-reference text indent)]
|
||||||
(assert (= a b)
|
(assert (= a b)
|
||||||
(string/format "reindent: %q, parse: %q (indent-test #%d with indent of %d)" a b indent-counter indent)
|
(string "indent " indent-counter " (indent=" indent ")"))))
|
||||||
)))
|
|
||||||
|
|
||||||
# Unix EOLs
|
|
||||||
(check-indent "" 0)
|
(check-indent "" 0)
|
||||||
(check-indent "\n" 0)
|
(check-indent "\n" 0)
|
||||||
(check-indent "\n" 1)
|
(check-indent "\n" 1)
|
||||||
@@ -115,17 +106,6 @@
|
|||||||
(check-indent "\n Hello, world!\n " 4)
|
(check-indent "\n Hello, world!\n " 4)
|
||||||
(check-indent "\n Hello, world!\n dedented text\n " 4)
|
(check-indent "\n Hello, world!\n dedented text\n " 4)
|
||||||
(check-indent "\n Hello, world!\n indented text\n " 4)
|
(check-indent "\n Hello, world!\n indented text\n " 4)
|
||||||
# Windows EOLs
|
|
||||||
(check-indent "\r\n" 0)
|
|
||||||
(check-indent "\r\n" 1)
|
|
||||||
(check-indent "\r\n\r\n" 0)
|
|
||||||
(check-indent "\r\n\r\n" 1)
|
|
||||||
(check-indent "\r\nHello, world!" 0)
|
|
||||||
(check-indent "\r\nHello, world!" 1)
|
|
||||||
(check-indent "\r\n Hello, world!\r\n " 4)
|
|
||||||
(check-indent "\r\n Hello, world!\r\n " 4)
|
|
||||||
(check-indent "\r\n Hello, world!\r\n dedented text\r\n " 4)
|
|
||||||
(check-indent "\r\n Hello, world!\r\n indented text\r\n " 4)
|
|
||||||
|
|
||||||
# Symbols with @ character
|
# Symbols with @ character
|
||||||
# d68eae9
|
# d68eae9
|
||||||
|
|||||||
@@ -664,8 +664,6 @@
|
|||||||
@[]) "peg if not")
|
@[]) "peg if not")
|
||||||
|
|
||||||
(defn test [name peg input expected]
|
(defn test [name peg input expected]
|
||||||
(assert-no-error "compile peg" (peg/compile peg))
|
|
||||||
(assert-no-error "marshal/unmarshal peg" (-> peg marshal unmarshal))
|
|
||||||
(assert (deep= (peg/match peg input) expected) name))
|
(assert (deep= (peg/match peg input) expected) name))
|
||||||
|
|
||||||
(test "sub: matches the same input twice"
|
(test "sub: matches the same input twice"
|
||||||
@@ -758,19 +756,5 @@
|
|||||||
"a,b,c"
|
"a,b,c"
|
||||||
@["a" "b" "c"])
|
@["a" "b" "c"])
|
||||||
|
|
||||||
(test "nth 1"
|
|
||||||
~{:prefix (number :d+ nil :n)
|
|
||||||
:word '(lenprefix (-> :n) :w)
|
|
||||||
:main (some (nth 1 (* :prefix ":" :word)))}
|
|
||||||
"5:apple6:banana6:cherry"
|
|
||||||
@["apple" "banana" "cherry"])
|
|
||||||
|
|
||||||
(test "only-tags 1"
|
|
||||||
~{:prefix (number :d+ nil :n)
|
|
||||||
:word (capture (lenprefix (-> :n) :w) :W)
|
|
||||||
:main (some (* (only-tags (* :prefix ":" :word)) (-> :W)))}
|
|
||||||
"5:apple6:banana6:cherry"
|
|
||||||
@["apple" "banana" "cherry"])
|
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2024 Calvin Rose
|
* Copyright (c) 2023 Calvin Rose
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
|||||||
Reference in New Issue
Block a user