forked from cory/tildefriends
Compare commits
117 Commits
f23414adaf
...
submodules
Author | SHA1 | Date | |
---|---|---|---|
e00f73e1d5 | |||
4c11667ebd | |||
658e7089be | |||
0965e90d7b | |||
d1f87a8fb4 | |||
2b4265f9ee | |||
3bd827a9f7 | |||
474e39c9c3 | |||
0272382e0e | |||
b1c8b51377 | |||
1a5acca5cf | |||
2d5417f7dc | |||
2a10d26215 | |||
b8e5caba0d | |||
a4b324127a | |||
acae3e9562 | |||
4aa7424977 | |||
758f177617 | |||
9291de41d8 | |||
3603ce5ba6 | |||
bff231751e | |||
fdda628be8 | |||
2b45d8aa05 | |||
0e2fc65301 | |||
e8ef7e74de | |||
c32e1b9583 | |||
9d0f6ec155 | |||
855d603795 | |||
af25782185 | |||
e5ba51b80a | |||
5e240de677 | |||
418cfac0e3 | |||
9d09607013 | |||
eddf25b622 | |||
537a8654fa | |||
9de33d06d2 | |||
0e5f320664 | |||
88d8e60511 | |||
439f07162e | |||
efe2b6cbd9 | |||
0aa1ed9464 | |||
cb94ed6a2a | |||
cf187ee46b | |||
3e71fc20fd | |||
f3601321f7 | |||
540059368c | |||
7ce89123f7 | |||
e3c7c86212 | |||
794804e27f | |||
6d89c1da6e | |||
d059554464 | |||
3a392d4a9f | |||
e3071b372a | |||
18bd279b0c | |||
5b93db7463 | |||
5b7e5eb91b | |||
78ca383e3c | |||
c1eed9ada3 | |||
8d6feb5394 | |||
42994f8977 | |||
f0a871e1f8 | |||
a710c30572 | |||
c991763b00 | |||
72dae14f87 | |||
5800340762 | |||
c5f5adcac6 | |||
591642efb3 | |||
6182ffa1d4 | |||
402a898d96 | |||
13d43d8319 | |||
7bcdbd3813 | |||
60ada22674 | |||
637119d46d | |||
40f3da6a65 | |||
f4697fe7f7 | |||
3bc18b9021 | |||
c21581aefa | |||
165f25db69 | |||
9aa0617aa1 | |||
ddce88dce6 | |||
6aa2bce2be | |||
a43c1d3d1e | |||
1ed0e817e8 | |||
709ca55e65 | |||
8c13f5dbba | |||
4cb82d81b7 | |||
0c42921387 | |||
70a3e7fc7d | |||
d5267be38c | |||
8e7e0ed490 | |||
8cf2837725 | |||
63ae186c76 | |||
dbf5c7b832 | |||
bfbfc01e99 | |||
8fa9d0e843 | |||
2d3e108fd9 | |||
7822b30dcb | |||
2701b7d04e | |||
e361c3f975 | |||
260706c172 | |||
390668ec34 | |||
1d5cdf9607 | |||
a4bf3542e0 | |||
df82cfe66b | |||
53f9547cc5 | |||
4bfd9de100 | |||
c01e00d77d | |||
825191c08f | |||
9dc6670795 | |||
1db8eee9f7 | |||
1bc50cb62c | |||
450b07fd08 | |||
12c7515ee8 | |||
ed65da4340 | |||
d9d2917cf5 | |||
ce5ca1875b | |||
4f869252a2 |
12
.gitignore
vendored
12
.gitignore
vendored
@ -1,2 +1,14 @@
|
||||
db.*
|
||||
deps/ios_toolchain/
|
||||
deps/openssl/
|
||||
dist/
|
||||
.keys
|
||||
**/node_modules
|
||||
out
|
||||
*.swo
|
||||
*.swp
|
||||
.zsign_cache/
|
||||
|
||||
deps/codemirror/cm6.js
|
||||
deps/prettier/standalone.mjs
|
||||
deps/lit
|
||||
|
22
.gitmodules
vendored
Normal file
22
.gitmodules
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
[submodule "deps/zlib"]
|
||||
path = deps/zlib
|
||||
url = https://github.com/madler/zlib.git
|
||||
branch = master
|
||||
[submodule "deps/libsodium"]
|
||||
path = deps/libsodium
|
||||
url = https://github.com/jedisct1/libsodium.git
|
||||
[submodule "deps/quickjs"]
|
||||
path = deps/quickjs
|
||||
url = https://github.com/bellard/quickjs.git
|
||||
[submodule "deps/crypt_blowfish"]
|
||||
path = deps/crypt_blowfish
|
||||
url = https://github.com/openwall/crypt_blowfish.git
|
||||
[submodule "deps/libbacktrace"]
|
||||
path = deps/libbacktrace
|
||||
url = https://github.com/ianlancetaylor/libbacktrace.git
|
||||
[submodule "deps/libuv"]
|
||||
path = deps/libuv
|
||||
url = https://github.com/libuv/libuv.git
|
||||
[submodule "deps/picohttpparser"]
|
||||
path = deps/picohttpparser
|
||||
url = https://github.com/h2o/picohttpparser.git
|
@ -3,8 +3,3 @@ useTabs: true
|
||||
semi: true
|
||||
singleQuote: true
|
||||
bracketSpacing: false
|
||||
# overrides:
|
||||
# - files: '**/*.json'
|
||||
# options:
|
||||
# useTabs: false
|
||||
# tabWidth: 2
|
||||
|
37
CONTRIBUTING.md
Normal file
37
CONTRIBUTING.md
Normal file
@ -0,0 +1,37 @@
|
||||
# Contributing to Tilde Friends
|
||||
|
||||
Thank you for your interest in Tilde Friends.
|
||||
|
||||
Above all, Tilde Friends aims to be a fun, safe place to play. When that is at
|
||||
odds with the course of development, we will work through it with respectful
|
||||
communication.
|
||||
|
||||
## How can I contribute?
|
||||
|
||||
The nature of Tilde Friends makes for a wide range of ways to contribute
|
||||
|
||||
- Just use it. Really, just kicking the tires will probably shake out issues
|
||||
in useful ways at this point.
|
||||
- Report and comment on bugs: https://dev.tildefriends.net/issues.
|
||||
- Make apps. You don't need my permission to make and share apps with Tilde
|
||||
Friends. I hope that an ecosystem of good apps grows outside of this
|
||||
repository. If you want to recreate better versions of the stock apps, just
|
||||
do it. If you make a better ssb app or whatever and drop me a line however
|
||||
is most convenient for you, I will probably take a look and consider
|
||||
replacing the stock one with it.
|
||||
- Write about it. Docs in the git repository, blog posts, private messages to
|
||||
me with ideas...really there is no wrong answer. Just make some noise, and
|
||||
I'll do my best to incorporate or otherwise link your feedback and make the
|
||||
most of it.
|
||||
- Write C code in the git repository. I'm really striving for it to be the
|
||||
case that other people don't really need to meddle in there, but if you can
|
||||
help out, I will gladly review your pull requests via
|
||||
https://dev.tildefriends.net/pulls.
|
||||
|
||||
## Best practices
|
||||
|
||||
- The C code is formatted with clang-format. Run `make format`.
|
||||
- The rest is formatted with prettier. Run `npm run prettier`.
|
||||
- We strive to have code compile on all platforms with no warnings and run with
|
||||
no sanitizer issues.
|
||||
- There are tests. Run `out/debug/tildefriends test`.
|
137
GNUmakefile
137
GNUmakefile
@ -3,16 +3,31 @@
|
||||
MAKEFLAGS += --warn-undefined-variables
|
||||
MAKEFLAGS += --no-builtin-rules
|
||||
|
||||
VERSION_CODE := 16
|
||||
VERSION_NUMBER := 0.0.16-wip
|
||||
VERSION_NAME := Medium English breakfast tea.
|
||||
VERSION_CODE := 17
|
||||
VERSION_NUMBER := 0.0.17-wip
|
||||
VERSION_NAME := Please enjoy responsibly.
|
||||
|
||||
SQLITE_URL := https://www.sqlite.org/2024/sqlite-amalgamation-3450200.zip
|
||||
|
||||
PROJECT = tildefriends
|
||||
BUILD_DIR ?= out
|
||||
UNAME_S := $(shell uname -s)
|
||||
UNAME_M := $(shell uname -m)
|
||||
|
||||
ANDROID_SDK ?= ~/Android/Sdk
|
||||
#ANDROID_SDK ?= ~/Android/Sdk
|
||||
ANDROID_SDK ?= /nix/store/54n9xsbb8gxa719g0bs7ghp336pax6mq-androidsdk/libexec/android-sdk
|
||||
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
ifneq ($(UNAME_S),Haiku)
|
||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
|
||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_M),aarch64)
|
||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
|
||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
BUILD_TYPES := macosdebug macosrelease iosdebug iosrelease iossimdebug iossimrelease
|
||||
@ -55,7 +70,7 @@ CFLAGS += \
|
||||
|
||||
ANDROID_BUILD_TOOLS := $(ANDROID_SDK)/build-tools/34.0.0
|
||||
ANDROID_PLATFORM := $(ANDROID_SDK)/platforms/android-34
|
||||
ANDROID_NDK ?= $(ANDROID_SDK)/ndk/26.1.10909125
|
||||
ANDROID_NDK ?= $(ANDROID_SDK)/ndk/26.2.11394342
|
||||
ANDROID_MIN_SDK_VERSION := 24
|
||||
ANDROID_TARGET_SDK_VERSION := 34
|
||||
|
||||
@ -207,18 +222,6 @@ $(IOS_TARGETS): LDFLAGS += -Ldeps/openssl/ios/ios64-xcrun/usr/local/lib
|
||||
$(IOSSIM_TARGETS): CFLAGS += -Ideps/openssl/ios/iossimulator-xcrun/usr/local/include
|
||||
$(IOSSIM_TARGETS): LDFLAGS += -Ldeps/openssl/ios/iossimulator-xcrun/usr/local/lib
|
||||
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
ifneq ($(UNAME_S),Haiku)
|
||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
|
||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_M),aarch64)
|
||||
debug: CFLAGS += -fsanitize=address -fsanitize=undefined -fno-common
|
||||
debug: LDFLAGS += -fsanitize=address -fsanitize=undefined
|
||||
endif
|
||||
|
||||
get_objs = \
|
||||
$(foreach build_type,$(BUILD_TYPES),$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)))))) \
|
||||
$(foreach build_type,debug release,$(addprefix $(BUILD_DIR)/$(build_type)/,$(addsuffix .o,$(basename $(value $(1)_unix))))) \
|
||||
@ -245,7 +248,6 @@ $(APP_OBJS): CFLAGS += \
|
||||
-Ideps/quickjs \
|
||||
-Ideps/sqlite \
|
||||
-Ideps/valgrind \
|
||||
-Ideps/xopt \
|
||||
-Wdouble-promotion \
|
||||
-Werror
|
||||
ifeq ($(UNAME_M),x86_64)
|
||||
@ -497,18 +499,6 @@ $(SQLITE_OBJS): CFLAGS += \
|
||||
-Wno-unused-function \
|
||||
-Wno-unused-variable
|
||||
|
||||
XOPT_SOURCES := deps/xopt/xopt.c
|
||||
XOPT_OBJS := $(call get_objs,XOPT_SOURCES)
|
||||
$(filter $(BUILD_DIR)/win%,$(XOPT_OBJS)): CFLAGS += \
|
||||
-DHAVE_SNPRINTF \
|
||||
-DHAVE_VSNPRINTF \
|
||||
-DHAVE_VASNPRINTF \
|
||||
-DHAVE_VASPRINTF \
|
||||
-Dvsnprintf=rpl_vsnprintf
|
||||
$(XOPT_OBJS): CFLAGS += \
|
||||
-Wno-implicit-const-int-float-conversion \
|
||||
-Wno-pointer-to-int-cast
|
||||
|
||||
QUICKJS_SOURCES := \
|
||||
deps/quickjs/cutils.c \
|
||||
deps/quickjs/libbf.c \
|
||||
@ -637,8 +627,7 @@ ALL_APP_OBJS := \
|
||||
$(QUICKJS_OBJS) \
|
||||
$(SODIUM_OBJS) \
|
||||
$(SQLITE_OBJS) \
|
||||
$(UV_OBJS) \
|
||||
$(XOPT_OBJS)
|
||||
$(UV_OBJS)
|
||||
|
||||
DEPS = $(ALL_APP_OBJS:.o=.d)
|
||||
-include $(DEPS)
|
||||
@ -696,6 +685,7 @@ out/res/drawable_icon.xml.flat: src/android/res/drawable/icon.xml
|
||||
|
||||
out/apk/res.apk out/gen/com/unprompted/tildefriends/R.java: out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat src/android/AndroidManifest.xml
|
||||
@mkdir -p $(dir $@)
|
||||
mkdir -p out/apk
|
||||
@$(ANDROID_BUILD_TOOLS)/aapt2 link -I $(ANDROID_PLATFORM)/android.jar out/res/layout_activity_main.xml.flat out/res/drawable_icon.xml.flat --manifest src/android/AndroidManifest.xml -o out/apk/res.apk --java out/gen/
|
||||
|
||||
JAVA_FILES := out/gen/com/unprompted/tildefriends/R.java $(wildcard src/android/com/unprompted/tildefriends/*.java)
|
||||
@ -717,7 +707,7 @@ PACKAGE_DIRS := \
|
||||
deps/prettier/ \
|
||||
deps/lit/
|
||||
|
||||
RAW_FILES := $(filter-out apps/blog% apps/gg% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f))
|
||||
RAW_FILES := $(filter-out apps/blog% apps/issues% apps/welcome% apps/journal% %.map, $(shell find $(PACKAGE_DIRS) -type f))
|
||||
|
||||
out/apk/TildeFriends-arm-debug.unsigned.apk: BUILD_TYPE := debug
|
||||
out/apk/TildeFriends-arm-release.unsigned.apk: BUILD_TYPE := release
|
||||
@ -736,10 +726,11 @@ out/apk/TildeFriends-arm-%.unsigned.apk:
|
||||
@cp out/android$(BUILD_TYPE)-armv7a/tildefriends out/apk-arm-$(BUILD_TYPE)/lib/armeabi-v7a/tildefriends.so
|
||||
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip out/apk-arm-$(BUILD_TYPE)/lib/arm64-v8a/tildefriends.so
|
||||
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip out/apk-arm-$(BUILD_TYPE)/lib/armeabi-v7a/tildefriends.so
|
||||
@cp out/apk/res.apk $@
|
||||
@cp out/apk/res.apk $@.zip
|
||||
@cp out/apk/classes.dex out/apk-arm-$(BUILD_TYPE)/
|
||||
@cd out/apk-arm-$(BUILD_TYPE) && zip -u ../../$@ -q -9 -r . && cd ../../
|
||||
@zip -u $@ -q -9 $(RAW_FILES)
|
||||
@cd out/apk-arm-$(BUILD_TYPE) && zip -u ../../$@.zip -q -9 -r . && cd ../../
|
||||
@zip -u $@.zip -q $(RAW_FILES)
|
||||
@$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $@.zip $@
|
||||
|
||||
out/apk/TildeFriends-x86-%.unsigned.apk:
|
||||
@mkdir -p $(dir $@) out/apk-x86-$(BUILD_TYPE)/lib/x86_64/ out/apk-x86-$(BUILD_TYPE)/lib/x86/
|
||||
@ -748,16 +739,22 @@ out/apk/TildeFriends-x86-%.unsigned.apk:
|
||||
@cp out/android$(BUILD_TYPE)-x86/tildefriends out/apk-x86-$(BUILD_TYPE)/lib/x86/tildefriends.so
|
||||
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip out/apk-x86-$(BUILD_TYPE)/lib/x86_64/tildefriends.so
|
||||
@$(ANDROID_NDK)/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-strip out/apk-x86-$(BUILD_TYPE)/lib/x86/tildefriends.so
|
||||
@cp out/apk/res.apk $@
|
||||
@cp out/apk/res.apk $@.zip
|
||||
@cp out/apk/classes.dex out/apk-x86-$(BUILD_TYPE)/
|
||||
@cd out/apk-x86-$(BUILD_TYPE) && zip -u ../../$@ -q -9 -r . && cd ../../
|
||||
@zip -u $@ -q -9 $(RAW_FILES)
|
||||
@cd out/apk-x86-$(BUILD_TYPE) && zip -u ../../$@.zip -q -9 -r . && cd ../../
|
||||
@zip -u $@.zip -q $(RAW_FILES)
|
||||
@$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $@.zip $@
|
||||
|
||||
out/%.apk: out/apk/%.unsigned.apk
|
||||
@echo "[apksigner] $(notdir $@)"
|
||||
@$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --out $@ $<
|
||||
@$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ $<
|
||||
|
||||
release-apk: out/TildeFriends-arm-release.apk out/TildeFriends-x86-release.apk
|
||||
out/%.zopfli.apk: out/%.apk
|
||||
@echo "[zopfli] $(notdir $@)"
|
||||
$(ANDROID_BUILD_TOOLS)/zipalign -f -z 4 $< $@.zopfli
|
||||
@$(ANDROID_BUILD_TOOLS)/apksigner sign --ks .keys/android.jks --ks-key-alias androidKey --ks-pass pass:android --key-pass pass:android --min-sdk-version $(ANDROID_MIN_SDK_VERSION) --out $@ $@.zopfli
|
||||
|
||||
release-apk: out/TildeFriends-arm-release.zopfli.apk out/TildeFriends-x86-release.zopfli.apk
|
||||
.PHONY: release-apk
|
||||
|
||||
releaseapkgo: out/TildeFriends-arm-release.apk
|
||||
@ -813,31 +810,46 @@ apklog:
|
||||
.PHONY: apklog
|
||||
|
||||
fetchdeps:
|
||||
@echo "[fetch] libuv"
|
||||
@test -f out/deps/libuv.tar.gz || (mkdir -p out/deps/ && curl -q https://dist.libuv.org/dist/v1.48.0/libuv-v1.48.0.tar.gz -o out/deps/libuv.tar.gz)
|
||||
@test -d deps/libuv/ || (mkdir -p deps/libuv/ && tar -C deps/libuv/ -m --strip=1 -xf out/deps/libuv.tar.gz)
|
||||
@echo "[fetch] sqlite"
|
||||
@test -f out/deps/sqlite.zip || (mkdir -p out/deps/ && curl -q https://www.sqlite.org/2024/sqlite-amalgamation-3450100.zip -o out/deps/sqlite.zip)
|
||||
@test -d deps/sqlite/ || (mkdir -p deps/sqlite/ && unzip -qDj -d deps/sqlite/ out/deps/sqlite.zip)
|
||||
@test -f out/deps/sqlite.zip && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p out/deps/ && curl -q $(SQLITE_URL) -o out/deps/sqlite.zip)
|
||||
@test -d deps/sqlite/ && test "$$(cat out/deps/sqlite.txt 2>/dev/null)" = $(SQLITE_URL) || (mkdir -p deps/sqlite/ && unzip -qDjo -d deps/sqlite/ out/deps/sqlite.zip)
|
||||
@echo -n $(SQLITE_URL) > out/deps/sqlite.txt
|
||||
@echo "[fetch] prettier"
|
||||
@test -f deps/prettier/standalone.mjs || curl -q --create-dirs -O --output-dir deps/prettier/ https://cdn.jsdelivr.net/npm/prettier@3.2.5/standalone.mjs
|
||||
@test -f deps/prettier/html.mjs || curl -q --create-dirs -O --output-dir deps/prettier/ https://cdn.jsdelivr.net/npm/prettier@3.2.5/plugins/html.mjs
|
||||
@test -f deps/prettier/babel.mjs || curl -q --create-dirs -O --output-dir deps/prettier/ https://cdn.jsdelivr.net/npm/prettier@3.2.5/plugins/babel.mjs
|
||||
@test -f deps/prettier/estree.mjs || curl -q --create-dirs -O --output-dir deps/prettier/ https://cdn.jsdelivr.net/npm/prettier@3.2.5/plugins/estree.mjs
|
||||
.PHONE: fetchdeps
|
||||
.PHONY: fetchdeps
|
||||
|
||||
ANDROID_DEPS := deps/openssl/android/arm64-v8a/usr/local/lib/libssl.a
|
||||
$(ANDROID_DEPS):
|
||||
+@tools/ssl-android
|
||||
$(filter $(BUILD_DIR)/android%,$(APP_OBJS)): | $(ANDROID_DEPS)
|
||||
|
||||
ifeq ($(HAVE_WIN),1)
|
||||
WINDOWS_DEPS := deps/openssl/mingw64/usr/local/lib/libssl.a
|
||||
$(WINDOWS_DEPS):
|
||||
+@tools/ssl-mingw64
|
||||
$(filter $(BUILD_DIR)/win%,$(APP_OBJS)): | $(WINDOWS_DEPS)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
IOS_DEPS := deps/openssl/ios/ios64-xcrun/usr/local/lib/libssl.a
|
||||
$(IOS_DEPS):
|
||||
+@tools/ssl-ios
|
||||
$(filter $(BUILD_DIR)/ios%,$(APP_OBJS)): | $(IOS_DEPS)
|
||||
endif
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
.PHONY: clean
|
||||
|
||||
dist: release-apk iosrelease-ipa
|
||||
@echo "[export] $$(svn info --show-item url)"
|
||||
@rm -rf tildefriends-$(VERSION_NUMBER)
|
||||
@svn export -q . tildefriends-$(VERSION_NUMBER)
|
||||
@echo "tildefriends-$(VERSION_NUMBER): $(VERSION_NAME)" > tildefriends-$(VERSION_NUMBER)/VERSION
|
||||
@echo "[tar] tildefriends-$(VERSION_NUMBER).tar.xz"
|
||||
@echo [archive] dist/tildefriends-$(VERSION_NUMBER).tar.xz
|
||||
@rm -rf out/tildefriends-$(VERSION_NUMBER)
|
||||
@mkdir -p dist/ out/tildefriends-$(VERSION_NUMBER)
|
||||
@git archive main | tar -x -C out/tildefriends-$(VERSION_NUMBER)
|
||||
@tar \
|
||||
--exclude=apps/gg* \
|
||||
--exclude=apps/welcome* \
|
||||
--exclude=deps/libbacktrace/Isaac.Newton-Opticks.txt \
|
||||
--exclude=deps/libsodium/builds/msvc/vs* \
|
||||
@ -852,14 +864,15 @@ dist: release-apk iosrelease-ipa
|
||||
--exclude=deps/sqlite/shell.c \
|
||||
--exclude=deps/zlib/contrib/vstudio \
|
||||
--exclude=deps/zlib/doc \
|
||||
-caf tildefriends-$(VERSION_NUMBER).tar.xz tildefriends-$(VERSION_NUMBER)
|
||||
@rm -rf tildefriends-$(VERSION_NUMBER)
|
||||
-caf dist/tildefriends-$(VERSION_NUMBER).tar.xz \
|
||||
-C out/ \
|
||||
tildefriends-$(VERSION_NUMBER)
|
||||
@echo "[cp] TildeFriends-x86-$(VERSION_NUMBER).apk"
|
||||
@cp out/TildeFriends-x86-release.apk TildeFriends-x86-$(VERSION_NUMBER).apk
|
||||
@cp out/TildeFriends-x86-release.zopfli.apk dist/TildeFriends-x86-$(VERSION_NUMBER).apk
|
||||
@echo "[cp] TildeFriends-arm-$(VERSION_NUMBER).apk"
|
||||
@cp out/TildeFriends-arm-release.apk TildeFriends-arm-$(VERSION_NUMBER).apk
|
||||
@cp out/TildeFriends-arm-release.zopfli.apk dist/TildeFriends-arm-$(VERSION_NUMBER).apk
|
||||
@echo "[cp] TildeFriends-$(VERSION_NUMBER).ipa"
|
||||
@cp out/tildefriends-release.ipa TildeFriends-$(VERSION_NUMBER).ipa
|
||||
@cp out/tildefriends-release.ipa dist/TildeFriends-$(VERSION_NUMBER).ipa
|
||||
.PHONY: dist
|
||||
|
||||
dist-test: dist
|
||||
@ -872,3 +885,11 @@ dist-test: dist
|
||||
format:
|
||||
@clang-format -i $(wildcard src/*.c src/*.h src/*.m)
|
||||
.PHONY: format
|
||||
|
||||
prettier:
|
||||
@npm run prettier
|
||||
.PHONY: prettier
|
||||
|
||||
docs:
|
||||
@doxygen
|
||||
.PHONY: docs
|
||||
|
32
README.md
32
README.md
@ -4,34 +4,46 @@ Tilde Friends is a tool for making and sharing.
|
||||
|
||||
A public instance lives at https://www.tildefriends.net/.
|
||||
|
||||
It is both a peer-to-peer social network client, participating in Secure Scuttlebutt, as well as a platform for writing and running web applications.
|
||||
It is both a peer-to-peer social network client, participating in Secure
|
||||
Scuttlebutt, as well as a platform for writing and running web applications.
|
||||
|
||||
## Goals
|
||||
|
||||
1. Make it easy and fun to run all sorts of web applications.
|
||||
2. Provide security that is easy to understand and protects your data.
|
||||
3. Make creating and sharing web applications accessible to anyone with a browser.
|
||||
3. Make creating and sharing web applications accessible to anyone with a
|
||||
browser.
|
||||
|
||||
## Building
|
||||
|
||||
Builds on Linux (x86_64 and aarch64), MacOS, OpenBSD, and Haiku. Builds for all of those host platforms plus mingw64, iOS, and android.
|
||||
Builds on Linux (x86_64 and aarch64), MacOS, OpenBSD, and Haiku. Builds for
|
||||
all of those host platforms plus mingw64, iOS, and android.
|
||||
|
||||
1. Requires openssl (`libssl-dev`, in debian-speak). All other dependencies are kept up to date in the tree.
|
||||
2. To build, run `make debug` or `make release`. An executable will be generated in a subdirectory of `out/`.
|
||||
3. It's possible to build for Android, iOS, and Windows on Linux, if you have the right dependencies in the right places. `make windebug winrelease iosdebug-ipa iosrelease-ipa release-apk`.
|
||||
1. Requires openssl (`libssl-dev`, in debian-speak). All other dependencies
|
||||
are kept up to date in the tree.
|
||||
2. To build, run `make debug` or `make release`. An executable will be
|
||||
generated in a subdirectory of `out/`.
|
||||
3. It's possible to build for Android, iOS, and Windows on Linux, if you have
|
||||
the right dependencies in the right places. `make windebug winrelease
|
||||
iosdebug-ipa iosrelease-ipa release-apk`.
|
||||
4. To build in docker, `docker build .`.
|
||||
5. `make format` will normalize formatting to the coding standard.
|
||||
|
||||
## Running
|
||||
|
||||
By default, running the built `tildefriends` executable will start a web server at <http://localhost:12345/>. `tildefriends -h` lists further options.
|
||||
By default, running the built `tildefriends` executable will start a web server
|
||||
at <http://localhost:12345/>. `tildefriends -h` lists further options.
|
||||
|
||||
The first user to create an account and log in will be granted administrative privileges. Further administration can be done at <http://localhost:12345/~core/admin/>.
|
||||
The first user to create an account and log in will be granted administrative
|
||||
privileges. Further administration can be done at
|
||||
<http://localhost:12345/~core/admin/>.
|
||||
|
||||
## Documentation
|
||||
|
||||
Docs are a work in progress: <https://www.tildefriends.net/~cory/wiki/#test-wiki/tf-app-quick-reference>.
|
||||
Docs are a work in progress:
|
||||
<https://www.tildefriends.net/~cory/wiki/#test-wiki/tf-app-quick-reference>.
|
||||
|
||||
## License
|
||||
|
||||
All code unless otherwise noted in is provided under the [MIT](https://opensource.org/licenses/MIT) license.
|
||||
All code unless otherwise noted in is provided under the
|
||||
[MIT](https://opensource.org/licenses/MIT) license.
|
||||
|
27
android-sdk.nix
Normal file
27
android-sdk.nix
Normal file
@ -0,0 +1,27 @@
|
||||
with import <nixpkgs> {};
|
||||
let
|
||||
androidComposition = androidenv.composeAndroidPackages {
|
||||
cmdLineToolsVersion = "9.0";
|
||||
toolsVersion = "26.1.1";
|
||||
platformToolsVersion = "34.0.5";
|
||||
buildToolsVersions = [ "34.0.0" ];
|
||||
includeEmulator = false;
|
||||
#emulatorVersion = "30.3.4";
|
||||
platformVersions = [ "34" ];
|
||||
includeSources = false;
|
||||
includeSystemImages = false;
|
||||
#systemImageTypes = [ "google_apis_playstore" ];
|
||||
#abiVersions = [ "armeabi-v7a" "arm64-v8a" ];
|
||||
#cmakeVersions = [ "3.10.2" ];
|
||||
includeNDK = true;
|
||||
ndkVersions = ["26.0.10792818"];
|
||||
useGoogleAPIs = false;
|
||||
useGoogleTVAddOns = false;
|
||||
#includeExtras = [
|
||||
# "extras;google;gcm"
|
||||
#];
|
||||
};
|
||||
in
|
||||
androidComposition.androidsdk
|
||||
|
||||
# $ NIXPKGS_ACCEPT_ANDROID_SDK_LICENSE=1 NIXPKGS_ALLOW_UNFREE=1 nix-build android-sdk.nix --impure
|
@ -87,6 +87,6 @@ window.addEventListener('load', function () {
|
||||
.map((x) => html`${input_template(x, data.settings[x])}`)}
|
||||
</div>
|
||||
${users_template(data.users)}
|
||||
</div>`;
|
||||
</div> `;
|
||||
render(page_template(g_data), document.body);
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "💻",
|
||||
"previous": "&RdVEsVscZm3aWzcMrEZS8mskO5tUmvaEUihex2MMfZQ=.sha256"
|
||||
"previous": "&icsPplXHgmpkbNWyo/WTvRdT/A8BXxW4lJixOtP4ueQ=.sha256"
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ async function fetch_shared_apps() {
|
||||
|
||||
await ssb.sqlAsync(
|
||||
`
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages_fts('"application/tildefriends"')
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
ORDER BY timestamp
|
||||
ORDER BY messages.timestamp
|
||||
`,
|
||||
[],
|
||||
function (row) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "💽"
|
||||
}
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "💽"
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🗺",
|
||||
"previous": "&0XSp+xdQwVtQ88bXzvWdH15Ex63hv5zUKTa4zx7HBGM=.sha256"
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
import * as tfrpc from '/tfrpc.js';
|
||||
import * as strava from './strava.js';
|
||||
|
||||
let g_database;
|
||||
let g_shared_database;
|
||||
|
||||
tfrpc.register(async function createIdentity() {
|
||||
return ssb.createIdentity();
|
||||
});
|
||||
tfrpc.register(async function appendMessage(id, message) {
|
||||
print('APPEND', JSON.stringify(message));
|
||||
return ssb.appendMessageWithIdentity(id, message);
|
||||
});
|
||||
tfrpc.register(function url() {
|
||||
return core.url;
|
||||
});
|
||||
tfrpc.register(async function getUser() {
|
||||
return core.user;
|
||||
});
|
||||
tfrpc.register(function getIdentities() {
|
||||
return ssb.getIdentities();
|
||||
});
|
||||
tfrpc.register(async function databaseGet(key) {
|
||||
return g_database ? g_database.get(key) : undefined;
|
||||
});
|
||||
tfrpc.register(async function databaseSet(key, value) {
|
||||
return g_database ? g_database.set(key, value) : undefined;
|
||||
});
|
||||
tfrpc.register(async function databaseRemove(key, value) {
|
||||
return g_database ? g_database.remove(key, value) : undefined;
|
||||
});
|
||||
tfrpc.register(async function sharedDatabaseGet(key) {
|
||||
return g_shared_database ? g_shared_database.get(key) : undefined;
|
||||
});
|
||||
tfrpc.register(async function sharedDatabaseSet(key, value) {
|
||||
return g_shared_database ? g_shared_database.set(key, value) : undefined;
|
||||
});
|
||||
tfrpc.register(async function sharedDatabaseRemove(key, value) {
|
||||
return g_shared_database ? g_shared_database.remove(key, value) : undefined;
|
||||
});
|
||||
tfrpc.register(async function query(sql, args) {
|
||||
let result = [];
|
||||
await ssb.sqlAsync(sql, args, function callback(row) {
|
||||
result.push(row);
|
||||
});
|
||||
return result;
|
||||
});
|
||||
tfrpc.register(async function store_blob(blob) {
|
||||
if (typeof blob == 'string') {
|
||||
blob = utf8Encode(blob);
|
||||
}
|
||||
if (Array.isArray(blob)) {
|
||||
blob = Uint8Array.from(blob);
|
||||
}
|
||||
return await ssb.blobStore(blob);
|
||||
});
|
||||
|
||||
tfrpc.register(async function get_blob(id) {
|
||||
return utf8Decode(await ssb.blobGet(id));
|
||||
});
|
||||
tfrpc.register(strava.refresh_token);
|
||||
|
||||
async function main() {
|
||||
g_shared_database = await shared_database('state');
|
||||
if (core.user.credentials?.session?.name) {
|
||||
g_database = await database('state');
|
||||
}
|
||||
|
||||
let attempt;
|
||||
if (core.user.credentials?.session?.name) {
|
||||
let shared_db = await shared_database('state');
|
||||
attempt = await shared_db.get(core.user.credentials.session.name);
|
||||
}
|
||||
app.setDocument(
|
||||
utf8Decode(getFile('index.html')).replace(
|
||||
'${data}',
|
||||
JSON.stringify({
|
||||
attempt: attempt,
|
||||
state: core.user?.credentials?.session?.name,
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
main();
|
File diff suppressed because one or more lines are too long
@ -1,84 +0,0 @@
|
||||
function xml_parse(xml) {
|
||||
let result;
|
||||
let path = [];
|
||||
let tag_begin;
|
||||
let text_begin;
|
||||
for (let i = 0; i < xml.length; i++) {
|
||||
let c = xml.charAt(i);
|
||||
if (!tag_begin && c == '<') {
|
||||
if (i > text_begin && path.length) {
|
||||
let value = xml.substring(text_begin, i);
|
||||
if (!/^\s*$/.test(value)) {
|
||||
path[path.length - 1].value = value;
|
||||
}
|
||||
}
|
||||
tag_begin = i + 1;
|
||||
} else if (tag_begin && c == '>') {
|
||||
let tag = xml.substring(tag_begin, i).trim();
|
||||
if (tag.startsWith('?') && tag.endsWith('?')) {
|
||||
/* Ignore directives. */
|
||||
} else if (tag.startsWith('/')) {
|
||||
path.pop();
|
||||
} else {
|
||||
let parts = tag.split(' ');
|
||||
let attributes = {};
|
||||
for (let j = 1; j < parts.length; j++) {
|
||||
let eq = parts[j].indexOf('=');
|
||||
let value = parts[j].substring(eq + 1);
|
||||
if (value.startsWith('"') && value.endsWith('"')) {
|
||||
value = value.substring(1, value.length - 1);
|
||||
}
|
||||
attributes[parts[j].substring(0, eq)] = value;
|
||||
}
|
||||
let next = {name: parts[0], children: [], attributes: attributes};
|
||||
if (path.length) {
|
||||
path[path.length - 1].children.push(next);
|
||||
} else {
|
||||
result = next;
|
||||
}
|
||||
if (!tag.endsWith('/')) {
|
||||
path.push(next);
|
||||
}
|
||||
}
|
||||
tag_begin = undefined;
|
||||
text_begin = i + 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function* xml_each(node, name) {
|
||||
for (let child of node.children) {
|
||||
if (child.name == name) {
|
||||
yield child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function gpx_parse(xml) {
|
||||
let result = {segments: []};
|
||||
let tree = xml_parse(xml);
|
||||
if (tree?.name == 'gpx') {
|
||||
for (let trk of xml_each(tree, 'trk')) {
|
||||
for (let trkseg of xml_each(trk, 'trkseg')) {
|
||||
let segment = [];
|
||||
for (let trkpt of xml_each(trkseg, 'trkpt')) {
|
||||
segment.push({
|
||||
lat: parseFloat(trkpt.attributes.lat),
|
||||
lon: parseFloat(trkpt.attributes.lon),
|
||||
});
|
||||
}
|
||||
result.segments.push(segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let metadata of xml_each(tree, 'metadata')) {
|
||||
for (let link of xml_each(metadata, 'link')) {
|
||||
result.link = link.attributes.href;
|
||||
}
|
||||
for (let time of xml_each(metadata, 'time')) {
|
||||
result.time = time.value;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
import * as strava from './strava.js';
|
||||
|
||||
async function main() {
|
||||
print('handler running');
|
||||
let r = await strava.authorization_code(request.query.code);
|
||||
print('state =', request.query.state);
|
||||
print('body = ', r.body);
|
||||
if (request.query.state && r.body) {
|
||||
let shared_db = await shared_database('state');
|
||||
await shared_db.set(request.query.state, utf8Decode(r.body));
|
||||
}
|
||||
await respond({
|
||||
data: r.body,
|
||||
content_type: 'text/plain',
|
||||
headers: {
|
||||
Location: 'https://tildefriends.net/~cory/gg/',
|
||||
},
|
||||
status_code: 307,
|
||||
});
|
||||
}
|
||||
main();
|
@ -1,26 +0,0 @@
|
||||
<!doctype html>
|
||||
<html style="width: 100%; height: 100%; margin: 0; padding: 0">
|
||||
<head>
|
||||
<script>
|
||||
window.litDisableBundleWarning = true;
|
||||
</script>
|
||||
<script>
|
||||
let g_data = ${data};
|
||||
</script>
|
||||
<script src="script.js" type="module"></script>
|
||||
<script src="leaflet.js"></script>
|
||||
</head>
|
||||
<body
|
||||
style="
|
||||
color: #fff;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
"
|
||||
>
|
||||
<gg-app style="width: 100%; height: 100%" id="ggapp"></gg-app>
|
||||
</body>
|
||||
</html>
|
@ -1,661 +0,0 @@
|
||||
/* required styles */
|
||||
|
||||
.leaflet-pane,
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-tile-container,
|
||||
.leaflet-pane > svg,
|
||||
.leaflet-pane > canvas,
|
||||
.leaflet-zoom-box,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-layer {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-container {
|
||||
overflow: hidden;
|
||||
}
|
||||
.leaflet-tile,
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-user-drag: none;
|
||||
}
|
||||
/* Prevents IE11 from highlighting tiles in blue */
|
||||
.leaflet-tile::selection {
|
||||
background: transparent;
|
||||
}
|
||||
/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
|
||||
.leaflet-safari .leaflet-tile {
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
/* hack that prevents hw layers "stretching" when loading new tiles */
|
||||
.leaflet-safari .leaflet-tile-container {
|
||||
width: 1600px;
|
||||
height: 1600px;
|
||||
-webkit-transform-origin: 0 0;
|
||||
}
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow {
|
||||
display: block;
|
||||
}
|
||||
/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
|
||||
/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
|
||||
.leaflet-container .leaflet-overlay-pane svg {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
}
|
||||
.leaflet-container .leaflet-marker-pane img,
|
||||
.leaflet-container .leaflet-shadow-pane img,
|
||||
.leaflet-container .leaflet-tile-pane img,
|
||||
.leaflet-container img.leaflet-image-layer,
|
||||
.leaflet-container .leaflet-tile {
|
||||
max-width: none !important;
|
||||
max-height: none !important;
|
||||
width: auto;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.leaflet-container img.leaflet-tile {
|
||||
/* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */
|
||||
mix-blend-mode: plus-lighter;
|
||||
}
|
||||
|
||||
.leaflet-container.leaflet-touch-zoom {
|
||||
-ms-touch-action: pan-x pan-y;
|
||||
touch-action: pan-x pan-y;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag {
|
||||
-ms-touch-action: pinch-zoom;
|
||||
/* Fallback for FF which doesn't support pinch-zoom */
|
||||
touch-action: none;
|
||||
touch-action: pinch-zoom;
|
||||
}
|
||||
.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
|
||||
-ms-touch-action: none;
|
||||
touch-action: none;
|
||||
}
|
||||
.leaflet-container {
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
.leaflet-container a {
|
||||
-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
|
||||
}
|
||||
.leaflet-tile {
|
||||
filter: inherit;
|
||||
visibility: hidden;
|
||||
}
|
||||
.leaflet-tile-loaded {
|
||||
visibility: inherit;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
width: 0;
|
||||
height: 0;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
z-index: 800;
|
||||
}
|
||||
/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
|
||||
.leaflet-overlay-pane svg {
|
||||
-moz-user-select: none;
|
||||
}
|
||||
|
||||
.leaflet-pane { z-index: 400; }
|
||||
|
||||
.leaflet-tile-pane { z-index: 200; }
|
||||
.leaflet-overlay-pane { z-index: 400; }
|
||||
.leaflet-shadow-pane { z-index: 500; }
|
||||
.leaflet-marker-pane { z-index: 600; }
|
||||
.leaflet-tooltip-pane { z-index: 650; }
|
||||
.leaflet-popup-pane { z-index: 700; }
|
||||
|
||||
.leaflet-map-pane canvas { z-index: 100; }
|
||||
.leaflet-map-pane svg { z-index: 200; }
|
||||
|
||||
.leaflet-vml-shape {
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
}
|
||||
.lvml {
|
||||
behavior: url(#default#VML);
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
|
||||
/* control positioning */
|
||||
|
||||
.leaflet-control {
|
||||
position: relative;
|
||||
z-index: 800;
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-top,
|
||||
.leaflet-bottom {
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-top {
|
||||
top: 0;
|
||||
}
|
||||
.leaflet-right {
|
||||
right: 0;
|
||||
}
|
||||
.leaflet-bottom {
|
||||
bottom: 0;
|
||||
}
|
||||
.leaflet-left {
|
||||
left: 0;
|
||||
}
|
||||
.leaflet-control {
|
||||
float: left;
|
||||
clear: both;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
float: right;
|
||||
}
|
||||
.leaflet-top .leaflet-control {
|
||||
margin-top: 10px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.leaflet-left .leaflet-control {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.leaflet-right .leaflet-control {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
|
||||
/* zoom and fade animations */
|
||||
|
||||
.leaflet-fade-anim .leaflet-popup {
|
||||
opacity: 0;
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
|
||||
opacity: 1;
|
||||
}
|
||||
.leaflet-zoom-animated {
|
||||
-webkit-transform-origin: 0 0;
|
||||
-ms-transform-origin: 0 0;
|
||||
transform-origin: 0 0;
|
||||
}
|
||||
svg.leaflet-zoom-animated {
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-animated {
|
||||
-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
-moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
transition: transform 0.25s cubic-bezier(0,0,0.25,1);
|
||||
}
|
||||
.leaflet-zoom-anim .leaflet-tile,
|
||||
.leaflet-pan-anim .leaflet-tile {
|
||||
-webkit-transition: none;
|
||||
-moz-transition: none;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.leaflet-zoom-anim .leaflet-zoom-hide {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
/* cursors */
|
||||
|
||||
.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
}
|
||||
.leaflet-grab {
|
||||
cursor: -webkit-grab;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
.leaflet-crosshair,
|
||||
.leaflet-crosshair .leaflet-interactive {
|
||||
cursor: crosshair;
|
||||
}
|
||||
.leaflet-popup-pane,
|
||||
.leaflet-control {
|
||||
cursor: auto;
|
||||
}
|
||||
.leaflet-dragging .leaflet-grab,
|
||||
.leaflet-dragging .leaflet-grab .leaflet-interactive,
|
||||
.leaflet-dragging .leaflet-marker-draggable {
|
||||
cursor: move;
|
||||
cursor: -webkit-grabbing;
|
||||
cursor: -moz-grabbing;
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
/* marker & overlays interactivity */
|
||||
.leaflet-marker-icon,
|
||||
.leaflet-marker-shadow,
|
||||
.leaflet-image-layer,
|
||||
.leaflet-pane > svg path,
|
||||
.leaflet-tile-container {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.leaflet-marker-icon.leaflet-interactive,
|
||||
.leaflet-image-layer.leaflet-interactive,
|
||||
.leaflet-pane > svg path.leaflet-interactive,
|
||||
svg.leaflet-image-layer.leaflet-interactive path {
|
||||
pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* visual tweaks */
|
||||
|
||||
.leaflet-container {
|
||||
background: #ddd;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
.leaflet-container a {
|
||||
color: #0078A8;
|
||||
}
|
||||
.leaflet-zoom-box {
|
||||
border: 2px dotted #38f;
|
||||
background: rgba(255,255,255,0.5);
|
||||
}
|
||||
|
||||
|
||||
/* general typography */
|
||||
.leaflet-container {
|
||||
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||
font-size: 12px;
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
|
||||
/* general toolbar styles */
|
||||
|
||||
.leaflet-bar {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.65);
|
||||
border-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #ccc;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
color: black;
|
||||
}
|
||||
.leaflet-bar a,
|
||||
.leaflet-control-layers-toggle {
|
||||
background-position: 50% 50%;
|
||||
background-repeat: no-repeat;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-bar a:hover,
|
||||
.leaflet-bar a:focus {
|
||||
background-color: #f4f4f4;
|
||||
}
|
||||
.leaflet-bar a:first-child {
|
||||
border-top-left-radius: 4px;
|
||||
border-top-right-radius: 4px;
|
||||
}
|
||||
.leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 4px;
|
||||
border-bottom-right-radius: 4px;
|
||||
border-bottom: none;
|
||||
}
|
||||
.leaflet-bar a.leaflet-disabled {
|
||||
cursor: default;
|
||||
background-color: #f4f4f4;
|
||||
color: #bbb;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-bar a {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:first-child {
|
||||
border-top-left-radius: 2px;
|
||||
border-top-right-radius: 2px;
|
||||
}
|
||||
.leaflet-touch .leaflet-bar a:last-child {
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
|
||||
/* zoom control */
|
||||
|
||||
.leaflet-control-zoom-in,
|
||||
.leaflet-control-zoom-out {
|
||||
font: bold 18px 'Lucida Console', Monaco, monospace;
|
||||
text-indent: 1px;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
|
||||
/* layers control */
|
||||
|
||||
.leaflet-control-layers {
|
||||
box-shadow: 0 1px 5px rgba(0,0,0,0.4);
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
.leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers.png);
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.leaflet-retina .leaflet-control-layers-toggle {
|
||||
background-image: url(images/layers-2x.png);
|
||||
background-size: 26px 26px;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers-toggle {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
}
|
||||
.leaflet-control-layers .leaflet-control-layers-list,
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
|
||||
display: none;
|
||||
}
|
||||
.leaflet-control-layers-expanded .leaflet-control-layers-list {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
.leaflet-control-layers-expanded {
|
||||
padding: 6px 10px 6px 6px;
|
||||
color: #333;
|
||||
background: #fff;
|
||||
}
|
||||
.leaflet-control-layers-scrollbar {
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
padding-right: 5px;
|
||||
}
|
||||
.leaflet-control-layers-selector {
|
||||
margin-top: 2px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
.leaflet-control-layers label {
|
||||
display: block;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
}
|
||||
.leaflet-control-layers-separator {
|
||||
height: 0;
|
||||
border-top: 1px solid #ddd;
|
||||
margin: 5px -10px 5px -6px;
|
||||
}
|
||||
|
||||
/* Default icon URLs */
|
||||
.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */
|
||||
background-image: url(images/marker-icon.png);
|
||||
}
|
||||
|
||||
|
||||
/* attribution and scale controls */
|
||||
|
||||
.leaflet-container .leaflet-control-attribution {
|
||||
background: #fff;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
.leaflet-control-attribution,
|
||||
.leaflet-control-scale-line {
|
||||
padding: 0 5px;
|
||||
color: #333;
|
||||
line-height: 1.4;
|
||||
}
|
||||
.leaflet-control-attribution a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.leaflet-control-attribution a:hover,
|
||||
.leaflet-control-attribution a:focus {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.leaflet-attribution-flag {
|
||||
display: inline !important;
|
||||
vertical-align: baseline !important;
|
||||
width: 1em;
|
||||
height: 0.6669em;
|
||||
}
|
||||
.leaflet-left .leaflet-control-scale {
|
||||
margin-left: 5px;
|
||||
}
|
||||
.leaflet-bottom .leaflet-control-scale {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
.leaflet-control-scale-line {
|
||||
border: 2px solid #777;
|
||||
border-top: none;
|
||||
line-height: 1.1;
|
||||
padding: 2px 5px 1px;
|
||||
white-space: nowrap;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
text-shadow: 1px 1px #fff;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child) {
|
||||
border-top: 2px solid #777;
|
||||
border-bottom: none;
|
||||
margin-top: -2px;
|
||||
}
|
||||
.leaflet-control-scale-line:not(:first-child):not(:last-child) {
|
||||
border-bottom: 2px solid #777;
|
||||
}
|
||||
|
||||
.leaflet-touch .leaflet-control-attribution,
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
box-shadow: none;
|
||||
}
|
||||
.leaflet-touch .leaflet-control-layers,
|
||||
.leaflet-touch .leaflet-bar {
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
|
||||
/* popup */
|
||||
|
||||
.leaflet-popup {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.leaflet-popup-content-wrapper {
|
||||
padding: 1px;
|
||||
text-align: left;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.leaflet-popup-content {
|
||||
margin: 13px 24px 13px 20px;
|
||||
line-height: 1.3;
|
||||
font-size: 13px;
|
||||
font-size: 1.08333em;
|
||||
min-height: 1px;
|
||||
}
|
||||
.leaflet-popup-content p {
|
||||
margin: 17px 0;
|
||||
margin: 1.3em 0;
|
||||
}
|
||||
.leaflet-popup-tip-container {
|
||||
width: 40px;
|
||||
height: 20px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-top: -1px;
|
||||
margin-left: -20px;
|
||||
overflow: hidden;
|
||||
pointer-events: none;
|
||||
}
|
||||
.leaflet-popup-tip {
|
||||
width: 17px;
|
||||
height: 17px;
|
||||
padding: 1px;
|
||||
|
||||
margin: -10px auto 0;
|
||||
pointer-events: auto;
|
||||
|
||||
-webkit-transform: rotate(45deg);
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
.leaflet-popup-content-wrapper,
|
||||
.leaflet-popup-tip {
|
||||
background: white;
|
||||
color: #333;
|
||||
box-shadow: 0 3px 14px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
font: 16px/24px Tahoma, Verdana, sans-serif;
|
||||
color: #757575;
|
||||
text-decoration: none;
|
||||
background: transparent;
|
||||
}
|
||||
.leaflet-container a.leaflet-popup-close-button:hover,
|
||||
.leaflet-container a.leaflet-popup-close-button:focus {
|
||||
color: #585858;
|
||||
}
|
||||
.leaflet-popup-scrolled {
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper {
|
||||
-ms-zoom: 1;
|
||||
}
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
width: 24px;
|
||||
margin: 0 auto;
|
||||
|
||||
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
|
||||
filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
|
||||
}
|
||||
|
||||
.leaflet-oldie .leaflet-control-zoom,
|
||||
.leaflet-oldie .leaflet-control-layers,
|
||||
.leaflet-oldie .leaflet-popup-content-wrapper,
|
||||
.leaflet-oldie .leaflet-popup-tip {
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
|
||||
/* div icon */
|
||||
|
||||
.leaflet-div-icon {
|
||||
background: #fff;
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
||||
/* Tooltip */
|
||||
/* Base styles for the element that has a tooltip */
|
||||
.leaflet-tooltip {
|
||||
position: absolute;
|
||||
padding: 6px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 3px;
|
||||
color: #222;
|
||||
white-space: nowrap;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
pointer-events: none;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.4);
|
||||
}
|
||||
.leaflet-tooltip.leaflet-interactive {
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.leaflet-tooltip-top:before,
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
border: 6px solid transparent;
|
||||
background: transparent;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* Directions */
|
||||
|
||||
.leaflet-tooltip-bottom {
|
||||
margin-top: 6px;
|
||||
}
|
||||
.leaflet-tooltip-top {
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before,
|
||||
.leaflet-tooltip-top:before {
|
||||
left: 50%;
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-top:before {
|
||||
bottom: 0;
|
||||
margin-bottom: -12px;
|
||||
border-top-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-bottom:before {
|
||||
top: 0;
|
||||
margin-top: -12px;
|
||||
margin-left: -6px;
|
||||
border-bottom-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-left {
|
||||
margin-left: -6px;
|
||||
}
|
||||
.leaflet-tooltip-right {
|
||||
margin-left: 6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before,
|
||||
.leaflet-tooltip-right:before {
|
||||
top: 50%;
|
||||
margin-top: -6px;
|
||||
}
|
||||
.leaflet-tooltip-left:before {
|
||||
right: 0;
|
||||
margin-right: -12px;
|
||||
border-left-color: #fff;
|
||||
}
|
||||
.leaflet-tooltip-right:before {
|
||||
left: 0;
|
||||
margin-left: -12px;
|
||||
border-right-color: #fff;
|
||||
}
|
||||
|
||||
/* Printing */
|
||||
|
||||
@media print {
|
||||
/* Prevent printers from removing background-images of controls. */
|
||||
.leaflet-control {
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
120
apps/gg/lit-all.min.js
vendored
120
apps/gg/lit-all.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,162 +0,0 @@
|
||||
/**
|
||||
* Based off of [the offical Google document](https://developers.google.com/maps/documentation/utilities/polylinealgorithm)
|
||||
*
|
||||
* Some parts from [this implementation](http://facstaff.unca.edu/mcmcclur/GoogleMaps/EncodePolyline/PolylineEncoder.js)
|
||||
* by [Mark McClure](http://facstaff.unca.edu/mcmcclur/)
|
||||
*
|
||||
* @module polyline
|
||||
*/
|
||||
|
||||
var polyline = {};
|
||||
|
||||
function py2_round(value) {
|
||||
// Google's polyline algorithm uses the same rounding strategy as Python 2, which is different from JS for negative values
|
||||
return Math.floor(Math.abs(value) + 0.5) * (value >= 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
function encode(current, previous, factor) {
|
||||
current = py2_round(current * factor);
|
||||
previous = py2_round(previous * factor);
|
||||
var coordinate = (current - previous) * 2;
|
||||
if (coordinate < 0) {
|
||||
coordinate = -coordinate - 1;
|
||||
}
|
||||
var output = '';
|
||||
while (coordinate >= 0x20) {
|
||||
output += String.fromCharCode((0x20 | (coordinate & 0x1f)) + 63);
|
||||
coordinate /= 32;
|
||||
}
|
||||
output += String.fromCharCode((coordinate | 0) + 63);
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes to a [latitude, longitude] coordinates array.
|
||||
*
|
||||
* This is adapted from the implementation in Project-OSRM.
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {Number} precision
|
||||
* @returns {Array}
|
||||
*
|
||||
* @see https://github.com/Project-OSRM/osrm-frontend/blob/master/WebContent/routing/OSRM.RoutingGeometry.js
|
||||
*/
|
||||
polyline.decode = function (str, precision) {
|
||||
var index = 0,
|
||||
lat = 0,
|
||||
lng = 0,
|
||||
coordinates = [],
|
||||
shift = 0,
|
||||
result = 0,
|
||||
byte = null,
|
||||
latitude_change,
|
||||
longitude_change,
|
||||
factor = Math.pow(10, Number.isInteger(precision) ? precision : 5);
|
||||
|
||||
// Coordinates have variable length when encoded, so just keep
|
||||
// track of whether we've hit the end of the string. In each
|
||||
// loop iteration, a single coordinate is decoded.
|
||||
while (index < str.length) {
|
||||
// Reset shift, result, and byte
|
||||
byte = null;
|
||||
shift = 1;
|
||||
result = 0;
|
||||
|
||||
do {
|
||||
byte = str.charCodeAt(index++) - 63;
|
||||
result += (byte & 0x1f) * shift;
|
||||
shift *= 32;
|
||||
} while (byte >= 0x20);
|
||||
|
||||
latitude_change = result & 1 ? (-result - 1) / 2 : result / 2;
|
||||
|
||||
shift = 1;
|
||||
result = 0;
|
||||
|
||||
do {
|
||||
byte = str.charCodeAt(index++) - 63;
|
||||
result += (byte & 0x1f) * shift;
|
||||
shift *= 32;
|
||||
} while (byte >= 0x20);
|
||||
|
||||
longitude_change = result & 1 ? (-result - 1) / 2 : result / 2;
|
||||
|
||||
lat += latitude_change;
|
||||
lng += longitude_change;
|
||||
|
||||
coordinates.push([lat / factor, lng / factor]);
|
||||
}
|
||||
|
||||
return coordinates;
|
||||
};
|
||||
|
||||
/**
|
||||
* Encodes the given [latitude, longitude] coordinates array.
|
||||
*
|
||||
* @param {Array.<Array.<Number>>} coordinates
|
||||
* @param {Number} precision
|
||||
* @returns {String}
|
||||
*/
|
||||
polyline.encode = function (coordinates, precision) {
|
||||
if (!coordinates.length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var factor = Math.pow(10, Number.isInteger(precision) ? precision : 5),
|
||||
output =
|
||||
encode(coordinates[0][0], 0, factor) +
|
||||
encode(coordinates[0][1], 0, factor);
|
||||
|
||||
for (var i = 1; i < coordinates.length; i++) {
|
||||
var a = coordinates[i],
|
||||
b = coordinates[i - 1];
|
||||
output += encode(a[0], b[0], factor);
|
||||
output += encode(a[1], b[1], factor);
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
function flipped(coords) {
|
||||
var flipped = [];
|
||||
for (var i = 0; i < coords.length; i++) {
|
||||
var coord = coords[i].slice();
|
||||
flipped.push([coord[1], coord[0]]);
|
||||
}
|
||||
return flipped;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a GeoJSON LineString feature/geometry.
|
||||
*
|
||||
* @param {Object} geojson
|
||||
* @param {Number} precision
|
||||
* @returns {String}
|
||||
*/
|
||||
polyline.fromGeoJSON = function (geojson, precision) {
|
||||
if (geojson && geojson.type === 'Feature') {
|
||||
geojson = geojson.geometry;
|
||||
}
|
||||
if (!geojson || geojson.type !== 'LineString') {
|
||||
throw new Error('Input must be a GeoJSON LineString');
|
||||
}
|
||||
return polyline.encode(flipped(geojson.coordinates), precision);
|
||||
};
|
||||
|
||||
/**
|
||||
* Decodes to a GeoJSON LineString geometry.
|
||||
*
|
||||
* @param {String} str
|
||||
* @param {Number} precision
|
||||
* @returns {Object}
|
||||
*/
|
||||
polyline.toGeoJSON = function (str, precision) {
|
||||
var coords = polyline.decode(str, precision);
|
||||
return {
|
||||
type: 'LineString',
|
||||
coordinates: flipped(coords),
|
||||
};
|
||||
};
|
||||
|
||||
let polyline_decode = polyline.decode;
|
||||
export {polyline_decode as decode};
|
@ -1,909 +0,0 @@
|
||||
import {
|
||||
LitElement,
|
||||
html,
|
||||
unsafeHTML,
|
||||
css,
|
||||
guard,
|
||||
until,
|
||||
} from './lit-all.min.js';
|
||||
import * as tfrpc from '/static/tfrpc.js';
|
||||
import * as polyline from './polyline.js';
|
||||
import {gpx_parse} from './gpx.js';
|
||||
|
||||
const k_client_id = '28276';
|
||||
const k_redirect_url = 'https://tildefriends.net/~cory/gg/login';
|
||||
|
||||
const k_color_snow = [128, 128, 255, 255];
|
||||
const k_color_ice = [160, 160, 255, 255];
|
||||
const k_color_water = [0, 0, 255, 255];
|
||||
const k_color_dirt = [128, 129, 130, 255];
|
||||
const k_color_pavement = [32, 32, 32, 255];
|
||||
const k_color_grass = [0, 255, 0, 255];
|
||||
const k_color_default = [128, 128, 128, 255];
|
||||
|
||||
const k_store = {
|
||||
'🦞': 15,
|
||||
'🛶': 10,
|
||||
'🏠': 10,
|
||||
'⛰': 10,
|
||||
'🐠': 10,
|
||||
};
|
||||
|
||||
const k_marker_snap = {x: 5, y: 4};
|
||||
|
||||
class GgAppElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
user: {type: Object},
|
||||
strava: {type: Object},
|
||||
activities: {type: Array},
|
||||
activity: {type: Object},
|
||||
world: {type: Object},
|
||||
whoami: {type: String},
|
||||
status: {type: Object},
|
||||
tab: {type: String},
|
||||
url: {type: String},
|
||||
currency: {type: Number},
|
||||
to_build: {type: String},
|
||||
emoji_of_the_day: {type: String},
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.activities = [];
|
||||
this.activity = {};
|
||||
this.loaded_activities = [];
|
||||
this.placed_emojis = [];
|
||||
this.strava = {};
|
||||
this.min_lat = Number.MAX_VALUE;
|
||||
this.min_lon = Number.MAX_VALUE;
|
||||
this.max_lat = -Number.MAX_VALUE;
|
||||
this.max_lon = -Number.MAX_VALUE;
|
||||
this.focus = undefined;
|
||||
this.status = undefined;
|
||||
this.tab = 'map';
|
||||
this.load().catch(function (e) {
|
||||
console.log('load error', e);
|
||||
});
|
||||
this.to_build = '🏠';
|
||||
}
|
||||
|
||||
async load() {
|
||||
console.log('load');
|
||||
let emojis = await (await fetch('emojis.json')).json();
|
||||
emojis = Object.values(emojis)
|
||||
.map((x) => Object.values(x))
|
||||
.flat();
|
||||
let today = new Date();
|
||||
let date_index =
|
||||
today.getYear() * 356 + today.getMonth() * 31 + today.getDate();
|
||||
this.emoji_of_the_day = emojis[(date_index * 123457) % emojis.length];
|
||||
this.user = await tfrpc.rpc.getUser();
|
||||
this.url = (await tfrpc.rpc.url()).split('?')[0];
|
||||
try {
|
||||
await this.update_credentials();
|
||||
} catch (e) {
|
||||
console.log('update_credentials failed', e);
|
||||
}
|
||||
try {
|
||||
await this.update_activities();
|
||||
} catch (e) {
|
||||
console.log('update_activities failed', e);
|
||||
}
|
||||
await this.acquire_ssb_identity();
|
||||
if (this.whoami && this.activities?.length) {
|
||||
await this.sync_activities();
|
||||
}
|
||||
await this.get_activities_from_ssb();
|
||||
}
|
||||
|
||||
/* https://gist.github.com/jcouyang/632709f30e12a7879a73e9e132c0d56b?permalink_comment_id=3591045#gistcomment-3591045 */
|
||||
async promise_all(promises, max_concurrent) {
|
||||
let index = 0;
|
||||
let results = [];
|
||||
async function exec_thread() {
|
||||
while (index < promises.length) {
|
||||
const current = index++;
|
||||
results[current] = await promises[current];
|
||||
}
|
||||
}
|
||||
const threads = [];
|
||||
for (let thread = 0; thread < max_concurrent; thread++) {
|
||||
threads.push(exec_thread());
|
||||
}
|
||||
await Promise.all(threads);
|
||||
return results;
|
||||
}
|
||||
|
||||
async get_activities_from_ssb() {
|
||||
this.status = {text: 'loading activities'};
|
||||
this.loaded_activities = [];
|
||||
let rows = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.author, json_extract(mention.value, '$.link') AS blob_id
|
||||
FROM messages_fts('"gg-activity"')
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid,
|
||||
json_each(messages.content, '$.mentions') as mention
|
||||
WHERE json_extract(messages.content, '$.type') = 'gg-activity' AND
|
||||
json_extract(mention.value, '$.name') = 'activity_data'
|
||||
ORDER BY messages.timestamp DESC
|
||||
`,
|
||||
[]
|
||||
);
|
||||
this.status = {text: 'loading activity data'};
|
||||
let authors = rows.map((x) => x.author);
|
||||
let blobs = await this.promise_all(
|
||||
rows.map((x) => tfrpc.rpc.get_blob(x.blob_id)),
|
||||
8
|
||||
);
|
||||
this.status = {text: 'processing activity data'};
|
||||
for (let [index, blob] of blobs.entries()) {
|
||||
let activity;
|
||||
try {
|
||||
activity = JSON.parse(blob);
|
||||
} catch {
|
||||
activity = gpx_parse(blob);
|
||||
}
|
||||
if (activity) {
|
||||
activity.author = authors[index];
|
||||
this.loaded_activities.push(activity);
|
||||
}
|
||||
}
|
||||
this.status = {text: 'calculating balance'};
|
||||
rows = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT count(*) AS currency FROM messages WHERE author = ? AND json_extract(content, '$.type') = 'gg-activity'
|
||||
`,
|
||||
[this.whoami]
|
||||
);
|
||||
let currency = rows[0].currency;
|
||||
rows = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT SUM(json_extract(content, '$.cost')) AS cost FROM messages WHERE author = ? AND json_extract(content, '$.type') = 'gg-place'
|
||||
`,
|
||||
[this.whoami]
|
||||
);
|
||||
let spent = rows[0].cost;
|
||||
this.currency = currency - spent;
|
||||
this.status = {text: 'getting placed emojis'};
|
||||
rows = await tfrpc.rpc.query(`
|
||||
SELECT messages.content
|
||||
FROM messages_fts('"gg-place"')
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
WHERE json_extract(messages.content, '$.type') = 'gg-place'
|
||||
ORDER BY messages.timestamp
|
||||
`);
|
||||
for (let row of rows) {
|
||||
console.log(row.content);
|
||||
let content = JSON.parse(row.content);
|
||||
this.placed_emojis.push({
|
||||
position: content.position,
|
||||
emoji: content.emoji,
|
||||
});
|
||||
}
|
||||
console.log(this.placed_emojis);
|
||||
this.status = undefined;
|
||||
this.update_map();
|
||||
}
|
||||
|
||||
async sync_activities() {
|
||||
let ids = this.activities.map(
|
||||
(x) => `https://www.strava.com/activities/${x.id}`
|
||||
);
|
||||
let missing = await tfrpc.rpc.query(
|
||||
`
|
||||
WITH my_activities AS (
|
||||
SELECT json_extract(mention.value, '$.link') AS url
|
||||
FROM messages, json_each(messages.content, '$.mentions') AS mention
|
||||
WHERE
|
||||
author = ? AND
|
||||
json_extract(messages.content, '$.type') = 'gg-activity' AND
|
||||
json_extract(mention.value, '$.name') = 'activity_url')
|
||||
SELECT from_strava.value FROM json_each(?) AS from_strava
|
||||
LEFT OUTER JOIN my_activities ON from_strava.value = my_activities.url
|
||||
WHERE my_activities.url IS NULL
|
||||
`,
|
||||
[this.whoami, JSON.stringify(ids)]
|
||||
);
|
||||
console.log('missing = ', missing);
|
||||
for (let [index, row] of missing.entries()) {
|
||||
this.status = {
|
||||
text: 'syncing from strava',
|
||||
value: index,
|
||||
max: missing.length,
|
||||
};
|
||||
let url = row.value;
|
||||
let id = url.match(/.*\/(\d+)/)[1];
|
||||
let response = await fetch(
|
||||
`https://www.strava.com/api/v3/activities/${id}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.strava.access_token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
let activity = await response.json();
|
||||
let blob_id = await tfrpc.rpc.store_blob(JSON.stringify(activity));
|
||||
let message = {
|
||||
type: 'gg-activity',
|
||||
mentions: [
|
||||
{
|
||||
link: url,
|
||||
name: 'activity_url',
|
||||
},
|
||||
{
|
||||
link: blob_id,
|
||||
name: 'activity_data',
|
||||
},
|
||||
],
|
||||
};
|
||||
await tfrpc.rpc.appendMessage(this.whoami, message);
|
||||
}
|
||||
this.status = undefined;
|
||||
}
|
||||
|
||||
async acquire_ssb_identity() {
|
||||
let user = await tfrpc.rpc.getUser();
|
||||
if (!user?.credentials?.session?.name) {
|
||||
return;
|
||||
}
|
||||
let ids = await tfrpc.rpc.getIdentities();
|
||||
let players = ids.length
|
||||
? (
|
||||
await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT author FROM messages JOIN json_each(?) ON messages.author = json_each.value
|
||||
WHERE
|
||||
json_extract(messages.content, '$.type') = 'gg-player' AND
|
||||
json_extract(messages.content, '$.active')
|
||||
ORDER BY timestamp DESC limit 1
|
||||
`,
|
||||
[JSON.stringify(ids)]
|
||||
)
|
||||
).map((row) => row.author)
|
||||
: [];
|
||||
if (!players.length) {
|
||||
this.whoami = await tfrpc.rpc.createIdentity();
|
||||
if (this.whoami) {
|
||||
await tfrpc.rpc.appendMessage(this.whoami, {
|
||||
type: 'gg-player',
|
||||
active: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
players.sort();
|
||||
this.whoami = players[0];
|
||||
}
|
||||
}
|
||||
|
||||
async update_credentials() {
|
||||
let name = this.user?.credentials?.session?.name;
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
let shared = await tfrpc.rpc.sharedDatabaseGet(name);
|
||||
if (shared) {
|
||||
await tfrpc.rpc.databaseSet('strava', shared);
|
||||
await tfrpc.rpc.sharedDatabaseRemove(name);
|
||||
}
|
||||
this.strava = JSON.parse((await tfrpc.rpc.databaseGet('strava')) || '{}');
|
||||
if (new Date().valueOf() / 1000 > this.strava.expires_at) {
|
||||
console.log(
|
||||
'this looks expired',
|
||||
new Date().valueOf() / 1000,
|
||||
'>',
|
||||
this.strava.expires_at
|
||||
);
|
||||
let x = await tfrpc.rpc.refresh_token(this.strava);
|
||||
if (x) {
|
||||
this.strava = x;
|
||||
await tfrpc.rpc.databaseSet('strava', JSON.stringify(x));
|
||||
} else {
|
||||
this.strava = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async update_activities() {
|
||||
if (this?.strava?.access_token) {
|
||||
let response = await fetch(
|
||||
'https://www.strava.com/api/v3/athlete/activities',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${this.strava.access_token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
this.activities = await response.json();
|
||||
this.activities.sort((a, b) => a.id - b.id);
|
||||
}
|
||||
}
|
||||
|
||||
color_to_emoji(color) {
|
||||
const k_map = [
|
||||
[k_color_snow, '⬜'],
|
||||
[k_color_ice, '🟦'],
|
||||
[k_color_water, '🟦'],
|
||||
[k_color_dirt, '🟫'],
|
||||
[k_color_pavement, '⬛'],
|
||||
[k_color_grass, '🟩'],
|
||||
[k_color_default, '🟧'],
|
||||
];
|
||||
for (let m of k_map) {
|
||||
if (
|
||||
m[0][0] == color[0] &&
|
||||
m[0][1] == color[1] &&
|
||||
m[0][2] == color[2] &&
|
||||
m[0][3] == color[3]
|
||||
) {
|
||||
return m[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
activity_bounds(activity) {
|
||||
let min_lat = Number.MAX_VALUE;
|
||||
let min_lon = Number.MAX_VALUE;
|
||||
let max_lat = -Number.MAX_VALUE;
|
||||
let max_lon = -Number.MAX_VALUE;
|
||||
if (activity?.map?.polyline) {
|
||||
for (let pt of polyline.decode(activity.map.polyline)) {
|
||||
min_lat = Math.min(min_lat, pt[0]);
|
||||
min_lon = Math.min(min_lon, pt[1]);
|
||||
max_lat = Math.max(max_lat, pt[0]);
|
||||
max_lon = Math.max(max_lon, pt[1]);
|
||||
}
|
||||
}
|
||||
if (activity?.segments) {
|
||||
for (let segment of activity.segments) {
|
||||
for (let pt of segment) {
|
||||
min_lat = Math.min(min_lat, pt.lat);
|
||||
min_lon = Math.min(min_lon, pt.lon);
|
||||
max_lat = Math.max(max_lat, pt.lat);
|
||||
max_lon = Math.max(max_lon, pt.lon);
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
min: {
|
||||
lat: min_lat,
|
||||
lng: min_lon,
|
||||
},
|
||||
max: {
|
||||
lat: max_lat,
|
||||
lng: max_lon,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
on_click(event) {
|
||||
let popup = L.popup()
|
||||
.setLatLng(event.latlng)
|
||||
.setContent(
|
||||
`
|
||||
<div><a target="_top" href="https://www.google.com/maps/search/?api=1&query=${event.latlng.lat},${event.latlng.lng}">${event.latlng.lat}, ${event.latlng.lng}</a></div>
|
||||
`
|
||||
)
|
||||
.openOn(this.leaflet);
|
||||
}
|
||||
|
||||
async build() {
|
||||
if (this.popup) {
|
||||
this.popup.remove();
|
||||
}
|
||||
if (!this.marker) {
|
||||
return;
|
||||
}
|
||||
let latlng = this.marker.getLatLng();
|
||||
|
||||
let cost = k_store[this.to_build];
|
||||
if (cost > this.currency) {
|
||||
alert('Insufficient funds.');
|
||||
return;
|
||||
}
|
||||
let message = {
|
||||
type: 'gg-place',
|
||||
position: {lat: latlng.lat, lng: latlng.lng},
|
||||
emoji: this.to_build,
|
||||
cost: cost,
|
||||
};
|
||||
let id = await tfrpc.rpc.appendMessage(this.whoami, message);
|
||||
this.marker.remove();
|
||||
this.placed_emojis.push({
|
||||
position: {lat: latlng.lat, lng: latlng.lng},
|
||||
emoji: this.to_build,
|
||||
});
|
||||
this.currency -= cost;
|
||||
return this.update_map();
|
||||
}
|
||||
|
||||
on_marker_click(event) {
|
||||
this.popup = L.popup()
|
||||
.setLatLng(event.latlng)
|
||||
.setContent(
|
||||
`
|
||||
${this.to_build} (-${k_store[this.to_build]}) <input type="button" value="Build" onclick="document.getElementById('ggapp').build()"></input>
|
||||
`
|
||||
)
|
||||
.openOn(this.leaflet);
|
||||
}
|
||||
|
||||
snap_to_grid(latlng, fudge, zoom) {
|
||||
let position = this.leaflet.options.crs.latLngToPoint(
|
||||
latlng,
|
||||
zoom ?? this.leaflet.getZoom()
|
||||
);
|
||||
position.x = Math.round(position.x / 16) * 16 + (fudge?.x ?? 0);
|
||||
position.y = Math.round(position.y / 16) * 16 + (fudge?.y ?? 0);
|
||||
position = this.leaflet.options.crs.pointToLatLng(
|
||||
position,
|
||||
zoom ?? this.leaflet.getZoom()
|
||||
);
|
||||
return position;
|
||||
}
|
||||
|
||||
on_marker_move(event) {
|
||||
if (!this.no_snap && this.marker) {
|
||||
this.no_snap = true;
|
||||
this.marker.setLatLng(
|
||||
this.snap_to_grid(this.marker.getLatLng(), k_marker_snap)
|
||||
);
|
||||
this.no_snap = false;
|
||||
}
|
||||
}
|
||||
|
||||
on_zoom(event) {
|
||||
if (this.marker) {
|
||||
this.marker.setLatLng(
|
||||
this.snap_to_grid(this.marker.getLatLng(), k_marker_snap)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
on_mouse_down(event) {
|
||||
if (this.marker) {
|
||||
this.marker.remove();
|
||||
this.marker = undefined;
|
||||
}
|
||||
|
||||
if (this.to_build) {
|
||||
this.marker = L.marker(this.snap_to_grid(event.latlng, k_marker_snap), {
|
||||
icon: L.divIcon({className: 'build-icon'}),
|
||||
draggable: true,
|
||||
}).addTo(this.leaflet);
|
||||
this.marker.on({click: this.on_marker_click.bind(this)});
|
||||
this.marker.on({drag: this.on_marker_move.bind(this)});
|
||||
}
|
||||
}
|
||||
|
||||
async update_map() {
|
||||
let map = this.shadowRoot.getElementById('map');
|
||||
if (!map || !this.loaded_activities.length) {
|
||||
this.leaflet = undefined;
|
||||
this.grid_layer = undefined;
|
||||
return;
|
||||
}
|
||||
if (!this.leaflet) {
|
||||
this.leaflet = L.map(map, {
|
||||
attributionControl: false,
|
||||
maxZoom: 16,
|
||||
bounceAtZoomLimits: false,
|
||||
});
|
||||
this.leaflet.on({contextmenu: this.on_click.bind(this)});
|
||||
this.leaflet.on({click: this.on_mouse_down.bind(this)});
|
||||
this.leaflet.on({zoom: this.on_zoom.bind(this)});
|
||||
}
|
||||
let self = this;
|
||||
let grid_layer = L.GridLayer.extend({
|
||||
createTile: function (coords) {
|
||||
var tile = L.DomUtil.create('canvas', 'leaflet-tile');
|
||||
var size = this.getTileSize();
|
||||
tile.width = size.x;
|
||||
tile.height = size.y;
|
||||
var context = tile.getContext('2d');
|
||||
context.font = '10pt sans';
|
||||
let bounds = this._tileCoordsToBounds(coords);
|
||||
let degrees = 360.0 / 2 ** coords.z;
|
||||
let ul = bounds.getNorthWest();
|
||||
let lr = bounds.getSouthEast();
|
||||
|
||||
let mini = document.createElement('canvas');
|
||||
mini.width = Math.floor(size.x / 16.0);
|
||||
mini.height = Math.floor(size.y / 16.0);
|
||||
let mini_context = mini.getContext('2d');
|
||||
let image_data = context.getImageData(0, 0, mini.width, mini.height);
|
||||
for (let activity of self.loaded_activities) {
|
||||
self.draw_activity_to_tile(
|
||||
image_data,
|
||||
mini.width,
|
||||
mini.height,
|
||||
ul,
|
||||
lr,
|
||||
activity
|
||||
);
|
||||
}
|
||||
context.textAlign = 'left';
|
||||
context.textBaseline = 'bottom';
|
||||
for (let x = 0; x < mini.width; x++) {
|
||||
for (let y = 0; y < mini.height; y++) {
|
||||
let start = (y * mini.width + x) * 4;
|
||||
let pixel = self.color_to_emoji(
|
||||
image_data.data.slice(start, start + 4)
|
||||
);
|
||||
if (pixel) {
|
||||
//context.fillRect(x * size.x / mini.width, y * size.y / mini.height, size.x / mini.width, size.y / mini.height);
|
||||
context.fillText(
|
||||
pixel,
|
||||
(x * size.x) / mini.width,
|
||||
(y * size.y) / mini.height + mini.height
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let placed of self.placed_emojis) {
|
||||
let position = self.leaflet.options.crs.latLngToPoint(
|
||||
self.snap_to_grid(placed.position, undefined, coords.z),
|
||||
coords.z
|
||||
);
|
||||
let tile_x = Math.floor(position.x / size.x);
|
||||
let tile_y = Math.floor(position.y / size.y);
|
||||
position.x = position.x - tile_x * size.x;
|
||||
position.y = position.y - tile_y * size.y;
|
||||
if (tile_x == coords.x && tile_y == coords.y) {
|
||||
//context.fillRect(position.x, position.y, size.x / mini.width, size.y / mini.height);
|
||||
context.fillText(
|
||||
placed.emoji,
|
||||
position.x,
|
||||
position.y + mini.height
|
||||
);
|
||||
}
|
||||
}
|
||||
return tile;
|
||||
},
|
||||
});
|
||||
if (this.grid_layer) {
|
||||
this.grid_layer.redraw();
|
||||
} else {
|
||||
this.grid_layer = new grid_layer();
|
||||
this.grid_layer.addTo(this.leaflet);
|
||||
}
|
||||
for (let activity of this.loaded_activities) {
|
||||
let bounds = this.activity_bounds(activity);
|
||||
this.min_lat = Math.min(this.min_lat, bounds.min.lat);
|
||||
this.min_lon = Math.min(this.min_lon, bounds.min.lng);
|
||||
this.max_lat = Math.max(this.max_lat, bounds.max.lat);
|
||||
this.max_lon = Math.max(this.max_lon, bounds.max.lng);
|
||||
}
|
||||
if (this.focus) {
|
||||
this.leaflet.fitBounds([this.focus.min, this.focus.max]);
|
||||
this.focus = undefined;
|
||||
} else {
|
||||
this.leaflet.fitBounds([
|
||||
[this.min_lat, this.min_lon],
|
||||
[this.max_lat, this.max_lon],
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
activity_to_color(activity) {
|
||||
let color = [0, 0, 0, 255];
|
||||
switch (activity.sport_type) {
|
||||
/* Implies snow. */
|
||||
case 'AlpineSki':
|
||||
case 'BackcountrySki':
|
||||
case 'NordicSki':
|
||||
case 'Snowshoe':
|
||||
case 'Snowboard':
|
||||
color = k_color_snow;
|
||||
break;
|
||||
|
||||
/* Implies ice. */
|
||||
case 'IceSkate':
|
||||
case 'InlineSkate':
|
||||
color = k_color_ice;
|
||||
break;
|
||||
|
||||
/* Implies water. */
|
||||
case 'Canoeing':
|
||||
case 'Kayaking':
|
||||
case 'Kitesurf':
|
||||
case 'Rowing':
|
||||
case 'Sail':
|
||||
case 'StandUpPaddling':
|
||||
case 'Surfing':
|
||||
case 'Swim':
|
||||
case 'Windsurf':
|
||||
color = k_color_water;
|
||||
break;
|
||||
|
||||
/* Implies dirt. */
|
||||
case 'EMountainBikeRide':
|
||||
case 'Hike':
|
||||
case 'MountainBikeRide':
|
||||
case 'RockClimbing':
|
||||
case 'TrailRun':
|
||||
color = k_color_dirt;
|
||||
break;
|
||||
|
||||
/* Implies pavement. */
|
||||
case 'EBikeRide':
|
||||
case 'GravelRide':
|
||||
case 'Handcycle':
|
||||
case 'Ride':
|
||||
case 'RollerSki':
|
||||
case 'Run':
|
||||
case 'Skateboard':
|
||||
case 'Badminton':
|
||||
case 'Tennis':
|
||||
case 'Velomobile':
|
||||
case 'Walk':
|
||||
case 'Wheelchair':
|
||||
color = k_color_pavement;
|
||||
break;
|
||||
|
||||
/* Grass, maybe? */
|
||||
case 'Golf':
|
||||
case 'Soccer':
|
||||
case 'Squash':
|
||||
color = k_color_grass;
|
||||
break;
|
||||
|
||||
// Crossfit,
|
||||
// Elliptical
|
||||
// HighIntensityIntervalTraining
|
||||
// Pickleball
|
||||
// Pilates
|
||||
// Racquetball
|
||||
// StairStepper
|
||||
// TableTennis,
|
||||
// VirtualRide
|
||||
// VirtualRow
|
||||
// VirtualRun
|
||||
// WeightTraining
|
||||
// Workout
|
||||
// Yoga
|
||||
default:
|
||||
color = k_color_default;
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
line(image_data, x0, y0, x1, y1, value) {
|
||||
/* <3 https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm */
|
||||
let dx = Math.abs(x1 - x0);
|
||||
let sx = x0 < x1 ? 1 : -1;
|
||||
let dy = -Math.abs(y1 - y0);
|
||||
let sy = y0 < y1 ? 1 : -1;
|
||||
let error = dx + dy;
|
||||
while (true) {
|
||||
if (
|
||||
x0 >= 0 &&
|
||||
y0 >= 0 &&
|
||||
x0 < image_data.width &&
|
||||
y0 < image_data.height
|
||||
) {
|
||||
let base = (y0 * image_data.width + x0) * 4;
|
||||
image_data.data[base + 0] = value[0];
|
||||
image_data.data[base + 1] = value[1];
|
||||
image_data.data[base + 2] = value[2];
|
||||
image_data.data[base + 3] = value[3];
|
||||
}
|
||||
|
||||
if (x0 == x1 && y0 == y1) {
|
||||
break;
|
||||
}
|
||||
let e2 = 2 * error;
|
||||
if (e2 >= dy) {
|
||||
if (x0 == x1) {
|
||||
break;
|
||||
}
|
||||
error += dy;
|
||||
x0 = Math.round(x0 + sx);
|
||||
}
|
||||
if (e2 <= dx) {
|
||||
if (y0 == y1) {
|
||||
break;
|
||||
}
|
||||
error += dx;
|
||||
y0 = Math.round(y0 + sy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_activity_to_tile(image_data, width, height, ul, lr, activity) {
|
||||
let color = this.activity_to_color(activity);
|
||||
if (activity?.map?.polyline) {
|
||||
let last;
|
||||
for (let pt of polyline.decode(activity.map.polyline)) {
|
||||
let px = [
|
||||
Math.floor((width * (pt[1] - ul.lng)) / (lr.lng - ul.lng)),
|
||||
Math.floor((height * (pt[0] - ul.lat)) / (lr.lat - ul.lat)),
|
||||
];
|
||||
if (last) {
|
||||
this.line(image_data, last[0], last[1], px[0], px[1], color);
|
||||
}
|
||||
last = px;
|
||||
}
|
||||
}
|
||||
if (activity?.segments) {
|
||||
for (let segment of activity.segments) {
|
||||
let last;
|
||||
for (let pt of segment) {
|
||||
let px = [
|
||||
Math.floor((width * (pt.lon - ul.lng)) / (lr.lng - ul.lng)),
|
||||
Math.floor((height * (pt.lat - ul.lat)) / (lr.lat - ul.lat)),
|
||||
];
|
||||
if (last) {
|
||||
this.line(image_data, last[0], last[1], px[0], px[1], color);
|
||||
}
|
||||
last = px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async on_upload(event) {
|
||||
try {
|
||||
let file = event.srcElement.files[0];
|
||||
let xml = await file.text();
|
||||
let gpx = gpx_parse(xml);
|
||||
let blob_id = await tfrpc.rpc.store_blob(xml);
|
||||
console.log('blob_id = ', blob_id);
|
||||
console.log(gpx);
|
||||
let message = {
|
||||
type: 'gg-activity',
|
||||
mentions: [
|
||||
{
|
||||
link: `https://${gpx.link}/activity/${gpx.time}`,
|
||||
name: 'activity_url',
|
||||
},
|
||||
{
|
||||
link: blob_id,
|
||||
name: 'activity_data',
|
||||
},
|
||||
],
|
||||
};
|
||||
console.log('id =', this.whoami, 'message = ', message);
|
||||
let id = await tfrpc.rpc.appendMessage(this.whoami, message);
|
||||
console.log('appended message', id);
|
||||
alert('Activity uploaded.');
|
||||
await this.get_activities_from_ssb();
|
||||
} catch (e) {
|
||||
alert(`Error: ${JSON.stringify(e, null, 2)}`);
|
||||
}
|
||||
}
|
||||
|
||||
upload() {
|
||||
let input = document.createElement('input');
|
||||
input.type = 'file';
|
||||
input.onchange = (event) => this.on_upload(event);
|
||||
input.click();
|
||||
}
|
||||
|
||||
updated() {
|
||||
this.update_map();
|
||||
}
|
||||
|
||||
focus_map(activity) {
|
||||
let bounds = this.activity_bounds(activity);
|
||||
if (bounds.min.lat < bounds.max.lat && bounds.min.lng < bounds.max.lng) {
|
||||
this.tab = 'map';
|
||||
this.focus = bounds;
|
||||
}
|
||||
}
|
||||
|
||||
render_news() {
|
||||
return html`
|
||||
<ul>
|
||||
${this.loaded_activities.map(
|
||||
(x) => html`
|
||||
<li style="cursor: pointer" @click=${() => this.focus_map(x)}>
|
||||
${x.author} ${x.name ?? x.time}
|
||||
</li>
|
||||
`
|
||||
)}
|
||||
</ul>
|
||||
`;
|
||||
}
|
||||
|
||||
render_store_item(item) {
|
||||
let [emoji, cost] = item;
|
||||
return html`
|
||||
<div>
|
||||
<input type="button" value="${emoji}" @click=${() => (this.to_build = emoji)}></input> ${cost} ${emoji == this.to_build ? '<-- Will be built next' : undefined}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
render_store() {
|
||||
let store = Object.assign({}, k_store);
|
||||
store[this.emoji_of_the_day] = 5;
|
||||
return html`
|
||||
<h2>Store</h2>
|
||||
<div><b>Your balance:</b> ${this.currency}</div>
|
||||
${Object.entries(store).map(this.render_store_item.bind(this))}
|
||||
`;
|
||||
}
|
||||
|
||||
render() {
|
||||
let header;
|
||||
if (!this.user?.credentials?.session?.name) {
|
||||
header = html`<div style="flex: 1 0">
|
||||
Please <a target="_top" href="/login?return=${this.url}">login</a> to
|
||||
Tilde Friends, first.
|
||||
</div>`;
|
||||
} else if (!this.strava?.access_token) {
|
||||
let strava_url = `https://www.strava.com/oauth/authorize?client_id=${k_client_id}&redirect_uri=${k_redirect_url}&response_type=code&approval_prompt=auto&scope=activity%3Aread&state=${g_data.state}`;
|
||||
header = html`
|
||||
<div style="flex: 1 0; display: flex; flex-direction: row; align-items: center; gap: 1em; width: 100%">
|
||||
<div style="flex: 1 1">Please <a target="_top" href=${strava_url}>login</a> to Strava.</div>
|
||||
<span style="font-size: xx-small; flex: 1 1; word-break: break-all">${this.whoami}</span>
|
||||
<input type="button" value="📁" @click=${this.upload}></input>
|
||||
</div>
|
||||
`;
|
||||
} else {
|
||||
header = html`
|
||||
<div>
|
||||
<div style="flex: 1 0; display: flex; flex-direction: row; align-items: center; gap: 1em; width: 100%">
|
||||
<h1>Welcome, ${this.user.credentials.session.name}</h1>
|
||||
<span style="font-size: xx-small; flex: 1 1; word-break: break-all">${this.whoami}</span>
|
||||
<input type="button" value="📁" @click=${this.upload}></input>
|
||||
</div>
|
||||
<h3 ?hidden=${!this.status?.text}>${this.status?.text} <progress ?hidden=${!this.status?.max} value=${this.status?.value} max=${this.status?.max}>${this.status?.value}</progress></h3>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
let navigation = html`
|
||||
<style>
|
||||
#navigation input[type="button"] {
|
||||
min-width: 3em;
|
||||
min-height: 3em;
|
||||
flex: 1 0;
|
||||
font-size: large;
|
||||
}
|
||||
</style>
|
||||
<div id="navigation" style="display: flex; flex-direction: row">
|
||||
<input type="button" id="button_map" @click=${() => (this.tab = 'map')} value="🗺️Map"></input>
|
||||
<input type="button" id="button_news" @click=${() => (this.tab = 'news')} value="🏃News"></input>
|
||||
<input type="button" id="button_friends" @click=${() => (this.tab = 'friends')} value="👫Friends"></input>
|
||||
<input type="button" id="button_store" @click=${() => (this.tab = 'store')} value="🏗️Store"></input>
|
||||
</div>
|
||||
`;
|
||||
|
||||
let content;
|
||||
switch (this.tab) {
|
||||
case 'map':
|
||||
content = html`<div id="map" style="width: 100%; height: 100%"></div>`;
|
||||
break;
|
||||
case 'news':
|
||||
content = this.render_news();
|
||||
break;
|
||||
case 'friends':
|
||||
content = html`<div>Friends</div>`;
|
||||
break;
|
||||
case 'store':
|
||||
content = this.render_store();
|
||||
break;
|
||||
}
|
||||
|
||||
return html`
|
||||
<style>
|
||||
.build-icon::before {
|
||||
content: '📍';
|
||||
border: 2px solid red;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="leaflet.css" />
|
||||
<div
|
||||
style="width: 100%; height: 100%; display: flex; flex-direction: column"
|
||||
>
|
||||
${header}
|
||||
<div style="flex: 1 0; overflow: scroll">${content}</div>
|
||||
${navigation}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
customElements.define('gg-app', GgAppElement);
|
@ -1,20 +0,0 @@
|
||||
const k_client_id = '28276';
|
||||
const k_client_secret = '3123f1f5afe132d9731111066d1d17bdb22ef27e';
|
||||
const k_access_token = 'f753e77764c26252bd2d80e7c5cc17ace51a8864';
|
||||
const k_refresh_token = 'f58d8e1b5a3ec3bf96e681589d5014f9a294f5a4';
|
||||
const k_redirect_url = 'https://tildefriends.net/~cory/gg/login';
|
||||
|
||||
export async function refresh_token(token) {
|
||||
let r = await fetch('https://www.strava.com/api/v3/oauth/token', {
|
||||
method: 'POST',
|
||||
body: `client_id=${k_client_id}&client_secret=${k_client_secret}&refresh_token=${token.refresh_token}&grant_type=refresh_token`,
|
||||
});
|
||||
return r?.body ? JSON.parse(utf8Decode(r.body)) : undefined;
|
||||
}
|
||||
|
||||
export async function authorization_code(code) {
|
||||
return await fetch('https://www.strava.com/api/v3/oauth/token', {
|
||||
method: 'POST',
|
||||
body: `client_id=${k_client_id}&client_secret=${k_client_secret}&code=${code}&grant_type=authorization_code`,
|
||||
});
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "📝",
|
||||
"previous": "&2hdIDbBrAg63T2X1MzdGSF7yiqHvlnfF0PnInQLp0DA=.sha256"
|
||||
"previous": "&b//KqE4Vx6kOSBRODK1p/8wjOLKZJ+CBB5IkaBt5YsM=.sha256"
|
||||
}
|
||||
|
5
apps/room.json
Normal file
5
apps/room.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "📦",
|
||||
"previous": "&IU+TwyM7TznD8NBfnw7tgW2zxVlMqTVxSqWFjuosLwo=.sha256"
|
||||
}
|
13
apps/room/app.js
Normal file
13
apps/room/app.js
Normal file
@ -0,0 +1,13 @@
|
||||
async function main() {
|
||||
let host = core.url.match(/.*\/\/(.*?)\//)[1];
|
||||
let id = (await ssb.getServerIdentity()).substring(1);
|
||||
let room = `net:${host}:${ssb.port}~shs:${id}:SSB+Room+SK3TLYC2T86EHQCUHBUHASCASE18JBV24=`;
|
||||
await app.setDocument(`
|
||||
<body style="color: #fff">
|
||||
<h1>Server</h1>
|
||||
<div>The local server address is:</div>
|
||||
<div><input type="text" readonly value="${room}" style="width: 100%"></input></div>
|
||||
</body>
|
||||
`);
|
||||
}
|
||||
main();
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "👟"
|
||||
"emoji": "👟",
|
||||
"previous": "&lYZRnT2UGQxXxYISbuaZewik9AuxBpcJumakwrePw5c=.sha256"
|
||||
}
|
||||
|
@ -38,10 +38,11 @@ class TfSneakerAppElement extends LitElement {
|
||||
}
|
||||
|
||||
format_message(message) {
|
||||
const k_flag_sequence_before_author = 1;
|
||||
let out = {
|
||||
previous: message.previous ?? null,
|
||||
};
|
||||
if (message.sequence_before_author) {
|
||||
if (message.flags & k_flag_sequence_before_author) {
|
||||
out.sequence = message.sequence;
|
||||
out.author = message.author;
|
||||
} else {
|
||||
@ -72,25 +73,104 @@ class TfSneakerAppElement extends LitElement {
|
||||
return true;
|
||||
}
|
||||
|
||||
// prettier-ignore
|
||||
if (startsWith(data, [0xff, 0xd8, 0xff, 0xdb]) ||
|
||||
startsWith(data, [0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01]) ||
|
||||
if (
|
||||
startsWith(data, [0xff, 0xd8, 0xff, 0xdb]) ||
|
||||
startsWith(
|
||||
data,
|
||||
[0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01]
|
||||
) ||
|
||||
startsWith(data, [0xff, 0xd8, 0xff, 0xee]) ||
|
||||
startsWith(data, [0xff, 0xd8, 0xff, 0xe1, null, null, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00])) {
|
||||
startsWith(data, [
|
||||
0xff,
|
||||
0xd8,
|
||||
0xff,
|
||||
0xe1,
|
||||
null,
|
||||
null,
|
||||
0x45,
|
||||
0x78,
|
||||
0x69,
|
||||
0x66,
|
||||
0x00,
|
||||
0x00,
|
||||
])
|
||||
) {
|
||||
return '.jpg';
|
||||
} else if (startsWith(data, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])) {
|
||||
} else if (
|
||||
startsWith(data, [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a])
|
||||
) {
|
||||
return '.png';
|
||||
} else if (startsWith(data, [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]) ||
|
||||
startsWith(data, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61])) {
|
||||
} else if (
|
||||
startsWith(data, [0x47, 0x49, 0x46, 0x38, 0x37, 0x61]) ||
|
||||
startsWith(data, [0x47, 0x49, 0x46, 0x38, 0x39, 0x61])
|
||||
) {
|
||||
return '.gif';
|
||||
} else if (startsWith(data, [0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50])) {
|
||||
} else if (
|
||||
startsWith(data, [
|
||||
0x52,
|
||||
0x49,
|
||||
0x46,
|
||||
0x46,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x57,
|
||||
0x45,
|
||||
0x42,
|
||||
0x50,
|
||||
])
|
||||
) {
|
||||
return '.webp';
|
||||
} else if (startsWith(data, [0x3c, 0x73, 0x76, 0x67])) {
|
||||
return '.svg';
|
||||
} else if (startsWith(data, [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34, 0x32])) {
|
||||
} else if (
|
||||
startsWith(data, [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x6d,
|
||||
0x70,
|
||||
0x34,
|
||||
0x32,
|
||||
])
|
||||
) {
|
||||
return '.mp3';
|
||||
} else if (startsWith(data, [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d]) ||
|
||||
startsWith(data, [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34, 0x32])) {
|
||||
} else if (
|
||||
startsWith(data, [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x69,
|
||||
0x73,
|
||||
0x6f,
|
||||
0x6d,
|
||||
]) ||
|
||||
startsWith(data, [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x6d,
|
||||
0x70,
|
||||
0x34,
|
||||
0x32,
|
||||
])
|
||||
) {
|
||||
return '.mp4';
|
||||
} else {
|
||||
return '.bin';
|
||||
@ -109,7 +189,12 @@ class TfSneakerAppElement extends LitElement {
|
||||
)[0].total;
|
||||
while (true) {
|
||||
let messages = await tfrpc.rpc.query(
|
||||
'SELECT * FROM messages WHERE author = ? AND SEQUENCE > ? ORDER BY sequence LIMIT 100',
|
||||
`
|
||||
SELECT author, id, sequence, timestamp, hash, json(content) AS content, signature, flags
|
||||
FROM messages
|
||||
WHERE author = ? AND SEQUENCE > ?
|
||||
ORDER BY sequence LIMIT 100
|
||||
`,
|
||||
[id, sequence]
|
||||
);
|
||||
if (messages?.length) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "🐌",
|
||||
"previous": "&DUxMMCJcuhm6S9jg/eKgEyWodkITu6Tg9g5I5wgLWFU=.sha256"
|
||||
"previous": "&Xs1X5TzLCk6KVr+5IDc80JAHYxJyoD10cXKBUYpFqWQ=.sha256"
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ class TfElement extends LitElement {
|
||||
let abouts = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT
|
||||
messages.*
|
||||
messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM
|
||||
messages,
|
||||
json_each(?1) AS following
|
||||
@ -118,7 +118,7 @@ class TfElement extends LitElement {
|
||||
json_extract(messages.content, '$.type') = 'about'
|
||||
UNION
|
||||
SELECT
|
||||
messages.*
|
||||
messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM
|
||||
messages,
|
||||
json_each(?2) AS following
|
||||
@ -158,7 +158,7 @@ class TfElement extends LitElement {
|
||||
async fetch_new_message(id) {
|
||||
let messages = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.*
|
||||
SELECT messages.id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||
FROM messages
|
||||
JOIN json_each(?) AS following ON messages.author = following.value
|
||||
WHERE messages.id = ?
|
||||
@ -221,7 +221,7 @@ class TfElement extends LitElement {
|
||||
this.tags = await tfrpc.rpc.query(
|
||||
`
|
||||
WITH
|
||||
recent AS (SELECT id, content FROM messages
|
||||
recent AS (SELECT id, json(content) AS content FROM messages
|
||||
WHERE messages.timestamp > ? AND json_extract(content, '$.type') = 'post'
|
||||
ORDER BY timestamp DESC LIMIT 1024),
|
||||
recent_channels AS (SELECT recent.id, '#' || json_extract(content, '$.channel') AS tag
|
||||
|
@ -262,7 +262,7 @@ class TfComposeElement extends LitElement {
|
||||
try {
|
||||
let rows = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.content FROM messages_fts(?)
|
||||
SELECT json(messages.content) FROM messages_fts(?)
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
WHERE messages.content LIKE ?
|
||||
ORDER BY timestamp DESC LIMIT 10
|
||||
|
@ -3,7 +3,7 @@ import * as tfrpc from '/static/tfrpc.js';
|
||||
import {styles} from './tf-styles.js';
|
||||
|
||||
/*
|
||||
* Provide a list of IDs, and this lets the user pick one.
|
||||
** Provide a list of IDs, and this lets the user pick one.
|
||||
*/
|
||||
class TfIdentityPickerElement extends LitElement {
|
||||
static get properties() {
|
||||
|
@ -265,10 +265,7 @@ ${JSON.stringify(mention, null, 2)}</pre
|
||||
new CustomEvent('tf-expand', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
id: (this.message.id || '') + (tag || ''),
|
||||
expanded: expanded,
|
||||
},
|
||||
detail: {id: (this.message.id || '') + (tag || ''), expanded: expanded},
|
||||
})
|
||||
);
|
||||
}
|
||||
@ -497,7 +494,7 @@ ${JSON.stringify(mention, null, 2)}</pre
|
||||
<tf-compose
|
||||
whoami=${this.whoami}
|
||||
.users=${this.users}
|
||||
root=${this.message.content.root || this.message.id}
|
||||
root=${content.root || this.message.id}
|
||||
branch=${this.message.id}
|
||||
.drafts=${this.drafts}
|
||||
@tf-discard=${this.discard_reply}
|
||||
@ -684,7 +681,7 @@ ${JSON.stringify(content, null, 2)}</pre
|
||||
<tf-compose
|
||||
whoami=${this.whoami}
|
||||
.users=${this.users}
|
||||
root=${this.message.content.root || this.message.id}
|
||||
root=${content.root || this.message.id}
|
||||
branch=${this.message.id}
|
||||
.drafts=${this.drafts}
|
||||
@tf-discard=${this.discard_reply}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -29,7 +29,7 @@ class TfTabMentionsElement extends LitElement {
|
||||
console.log('Loading...', this.whoami);
|
||||
let results = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages_fts(?)
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
JOIN json_each(?) AS following ON messages.author = following.value
|
||||
|
@ -33,12 +33,12 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
if (this.hash.startsWith('#@')) {
|
||||
let r = await tfrpc.rpc.query(
|
||||
`
|
||||
WITH mine AS (SELECT messages.*
|
||||
WITH mine AS (SELECT id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||
FROM messages
|
||||
WHERE messages.author = ?
|
||||
ORDER BY sequence DESC
|
||||
LIMIT 20)
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM mine
|
||||
JOIN messages_refs ON mine.id = messages_refs.ref
|
||||
JOIN messages ON messages_refs.message = messages.id
|
||||
@ -51,11 +51,11 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
} else if (this.hash.startsWith('#%')) {
|
||||
return await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.*
|
||||
SELECT id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||
FROM messages
|
||||
WHERE id = ?1
|
||||
UNION
|
||||
SELECT messages.*
|
||||
SELECT id, previous, author, sequence, timestamp, hash, json(content) AS content, signature
|
||||
FROM messages JOIN messages_refs
|
||||
ON messages.id = messages_refs.message
|
||||
WHERE messages_refs.ref = ?1
|
||||
@ -69,17 +69,17 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
promises.push(
|
||||
tfrpc.rpc.query(
|
||||
`
|
||||
WITH news AS (SELECT messages.*
|
||||
WITH news AS (SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages
|
||||
JOIN json_each(?) AS following ON messages.author = following.value
|
||||
WHERE messages.timestamp > ? AND messages.timestamp < ?
|
||||
ORDER BY messages.timestamp DESC)
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM news
|
||||
JOIN messages_refs ON news.id = messages_refs.ref
|
||||
JOIN messages ON messages_refs.message = messages.id
|
||||
UNION
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM news
|
||||
JOIN messages_refs ON news.id = messages_refs.message
|
||||
JOIN messages ON messages_refs.ref = messages.id
|
||||
@ -107,18 +107,18 @@ class TfTabNewsFeedElement extends LitElement {
|
||||
this.start_time = last_start_time - 24 * 60 * 60 * 1000;
|
||||
let more = await tfrpc.rpc.query(
|
||||
`
|
||||
WITH news AS (SELECT messages.*
|
||||
WITH news AS (SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages
|
||||
JOIN json_each(?) AS following ON messages.author = following.value
|
||||
WHERE messages.timestamp > ?
|
||||
AND messages.timestamp <= ?
|
||||
ORDER BY messages.timestamp DESC)
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM news
|
||||
JOIN messages_refs ON news.id = messages_refs.ref
|
||||
JOIN messages ON messages_refs.message = messages.id
|
||||
UNION
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM news
|
||||
JOIN messages_refs ON news.id = messages_refs.message
|
||||
JOIN messages ON messages_refs.ref = messages.id
|
||||
|
@ -35,7 +35,7 @@ class TfTabSearchElement extends LitElement {
|
||||
await tfrpc.rpc.setHash('#q=' + encodeURIComponent(query));
|
||||
let results = await tfrpc.rpc.query(
|
||||
`
|
||||
SELECT messages.*
|
||||
SELECT messages.id, messages.previous, messages.author, messages.sequence, messages.timestamp, messages.hash, json(messages.content) AS content, messages.signature
|
||||
FROM messages_fts(?)
|
||||
JOIN messages ON messages.rowid = messages_fts.rowid
|
||||
JOIN json_each(?) AS following ON messages.author = following.value
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"type": "tildefriends-app",
|
||||
"emoji": "📝",
|
||||
"previous": "&/wl8HE2jZShRXTYEVYRrK3pjHwi41Wbxl9HoSJaQP6Y=.sha256"
|
||||
"previous": "&DnfuAUGzzalSh9NgZXnzDc9Ru5aM0omfRJ4h27jYw4k=.sha256"
|
||||
}
|
||||
|
@ -2,8 +2,9 @@
|
||||
<html>
|
||||
<head>
|
||||
<base target="_top" />
|
||||
<link rel="stylesheet" href="tildefriends.css" />
|
||||
</head>
|
||||
<body style="color: #fff">
|
||||
<body>
|
||||
<tf-collections-app></tf-collections-app>
|
||||
<script>
|
||||
window.litDisableBundleWarning = true;
|
||||
|
@ -5,6 +5,7 @@ class TfCollectionElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
whoami: {type: String},
|
||||
category: {type: String},
|
||||
collection: {type: Object},
|
||||
selected_id: {type: String},
|
||||
is_creating: {type: Boolean},
|
||||
@ -75,9 +76,10 @@ class TfCollectionElement extends LitElement {
|
||||
render() {
|
||||
let self = this;
|
||||
return html`
|
||||
<span style="display: inline-flex; flex-direction: row">
|
||||
<link rel="stylesheet" href="tildefriends.css"/>
|
||||
<span class="inline-flex-row">
|
||||
<select @change=${this.on_selected} id="select" value=${this.selected_id}>
|
||||
<option value="" ?selected=${this.selected_id === ''} disabled hidden>(select)</option>
|
||||
<option value="" ?selected=${this.selected_id === ''} disabled hidden>(select ${this.category})</option>
|
||||
${Object.values(this.collection ?? {})
|
||||
.sort((x, y) => x.name.localeCompare(y.name))
|
||||
.map(
|
||||
@ -91,22 +93,22 @@ class TfCollectionElement extends LitElement {
|
||||
)}
|
||||
</select>
|
||||
<span ?hidden=${!this.is_renaming || !this.whoami}>
|
||||
<span style="display: inline-flex; flex-direction: row; margin-left: 8px; margin-right: 8px">
|
||||
<span class="inline-flex-row" style="margin-left: 8px; margin-right: 8px">
|
||||
<label for="rename_name">🏷Rename to:</label>
|
||||
<input type="text" id="rename_name"></input>
|
||||
<button @click=${this.on_rename}>Rename ${this.type}</button>
|
||||
<button @click=${() => (self.is_renaming = false)}>x</button>
|
||||
</span>
|
||||
</span>
|
||||
<button @click=${() => (self.is_renaming = true)} ?disabled=${this.is_renaming || !this.selected_id} ?hidden=${!this.whoami}>🏷</button>
|
||||
<button @click=${self.on_tombstone} ?disabled=${!this.selected_id} ?hidden=${!this.whoami}>🪦</button>
|
||||
<button class="yellow" @click=${() => (self.is_renaming = true)} ?disabled=${this.is_renaming || !this.selected_id} ?hidden=${!this.whoami}>🏷</button>
|
||||
<button class="red" @click=${self.on_tombstone} ?disabled=${!this.selected_id} ?hidden=${!this.whoami}>🪦</button>
|
||||
<span ?hidden=${!this.is_creating || !this.whoami}>
|
||||
<label for="create_name">New ${this.type} name:</label>
|
||||
<input type="text" id="create_name"></input>
|
||||
<button @click=${this.on_create}>Create ${this.type}</button>
|
||||
<button @click=${() => (self.is_creating = false)}>x</button>
|
||||
</span>
|
||||
<button @click=${() => (self.is_creating = true)} ?hidden=${this.is_creating || !this.whoami}>+</button>
|
||||
<button class="green" @click=${() => (self.is_creating = true)} ?hidden=${this.is_creating || !this.whoami}>+</button>
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ class TfIdentityPickerElement extends LitElement {
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<link rel="stylesheet" href="tildefriends.css" />
|
||||
<select @change=${this.changed} style="max-width: 100%">
|
||||
${(this.ids ?? []).map(
|
||||
(id) =>
|
||||
|
@ -255,12 +255,22 @@ class TfCollectionsAppElement extends LitElement {
|
||||
render() {
|
||||
let self = this;
|
||||
return html`
|
||||
<link rel="stylesheet" href="tildefriends.css"/>
|
||||
<style>
|
||||
.toc:hover {
|
||||
.toc-item {
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.toc-item:hover {
|
||||
background-color: #0cc;
|
||||
}
|
||||
.toc.selected {
|
||||
.toc-item.selected {
|
||||
background-color: #088;
|
||||
font-weight: bold;
|
||||
}
|
||||
.table-of-contents {
|
||||
flex: 0 0;
|
||||
margin-right: 16px;
|
||||
}
|
||||
</style>
|
||||
<div>
|
||||
@ -272,6 +282,7 @@ class TfCollectionsAppElement extends LitElement {
|
||||
html`<tf-collection
|
||||
.collection=${this.wikis}
|
||||
whoami=${this.whoami}
|
||||
category="wiki"
|
||||
selected_id=${this.wiki?.id}
|
||||
@create=${this.on_wiki_create}
|
||||
@rename=${this.on_wiki_rename}
|
||||
@ -284,6 +295,7 @@ class TfCollectionsAppElement extends LitElement {
|
||||
html`<tf-collection
|
||||
.collection=${this.wiki_docs}
|
||||
whoami=${this.whoami}
|
||||
category="document"
|
||||
selected_id=${this.wiki_doc &&
|
||||
this.wiki_doc?.parent == this.wiki?.id
|
||||
? this.wiki_doc?.id
|
||||
@ -298,9 +310,9 @@ class TfCollectionsAppElement extends LitElement {
|
||||
<div ?hidden=${!this.wiki?.editors || !this.expand_editors}>
|
||||
<div>
|
||||
<ul>
|
||||
${this.wiki?.editors.map((id) => html`<li><button ?hidden=${id == this.whoami} @click=${() => self.on_remove_editor(id)}>x</button> ${id}</li>`)}
|
||||
${this.wiki?.editors.map((id) => html`<li><button class="red" ?hidden=${id == this.whoami} @click=${() => self.on_remove_editor(id)}>x</button> ${id}</li>`)}
|
||||
<li>
|
||||
<button @click=${() => (self.adding_editor = true)} ?hidden=${this.wiki?.editors?.indexOf(this.whoami) == -1 || this.adding_editor}>+</button>
|
||||
<button class="green" @click=${() => (self.adding_editor = true)} ?hidden=${this.wiki?.editors?.indexOf(this.whoami) == -1 || this.adding_editor}>+</button>
|
||||
<div ?hidden=${!this.adding_editor}>
|
||||
<label for="add_editor">Add Editor:</label>
|
||||
<input type="text" id="add_editor"></input>
|
||||
@ -312,18 +324,19 @@ class TfCollectionsAppElement extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: row">
|
||||
<div style="flex: 0 0">
|
||||
<div class="flex-row">
|
||||
<div class="box table-of-contents">
|
||||
${Object.values(this.wikis || {})
|
||||
.sort((x, y) => x.name.localeCompare(y.name))
|
||||
.map(
|
||||
(wiki) => html`
|
||||
<div
|
||||
class="toc ${self.wiki?.id === wiki.id ? 'selected' : ''}"
|
||||
style="white-space: nowrap; cursor: pointer"
|
||||
class="toc-item ${self.wiki?.id === wiki.id
|
||||
? 'selected'
|
||||
: ''}"
|
||||
@click=${() => self.on_wiki_changed({detail: {value: wiki}})}
|
||||
>
|
||||
${wiki.name}
|
||||
${self.wiki?.id === wiki.id ? '' : '>'} ${wiki.name}
|
||||
</div>
|
||||
<ul>
|
||||
${Object.values(self.wiki_docs || {})
|
||||
@ -332,14 +345,12 @@ class TfCollectionsAppElement extends LitElement {
|
||||
.map(
|
||||
(doc) => html`
|
||||
<li
|
||||
class="toc ${self.wiki_doc?.id === doc.id
|
||||
class="toc-item ${self.wiki_doc?.id === doc.id
|
||||
? 'selected'
|
||||
: ''}"
|
||||
style="white-space: nowrap; cursor: pointer; list-style: none; text-indent: -1rem"
|
||||
style="list-style: none; text-indent: -1rem"
|
||||
@click=${() =>
|
||||
self.on_wiki_doc_changed({
|
||||
detail: {value: doc},
|
||||
})}
|
||||
self.on_wiki_doc_changed({detail: {value: doc}})}
|
||||
>
|
||||
${doc?.private ? '🔒' : '📄'} ${doc.name}
|
||||
</li>
|
||||
|
@ -84,7 +84,11 @@ class TfWikiDocElement extends LitElement {
|
||||
|
||||
async load_blob() {
|
||||
let blob = await tfrpc.rpc.get_blob(this.value?.blob);
|
||||
if (blob.endsWith('.box')) {
|
||||
if (!blob) {
|
||||
console.warn(
|
||||
"no blob found, we're going to assume the document is empty (load_blob())"
|
||||
);
|
||||
} else if (blob.endsWith('.box')) {
|
||||
let d = await tfrpc.rpc.try_decrypt(this.whoami, blob);
|
||||
if (d) {
|
||||
blob = d;
|
||||
@ -253,85 +257,43 @@ class TfWikiDocElement extends LitElement {
|
||||
let self = this;
|
||||
let thumbnail_ref = this.thumbnail(this.blob);
|
||||
return html`
|
||||
<link rel="stylesheet" href="tildefriends.css"/>
|
||||
<style>
|
||||
a:link {
|
||||
color: #268bd2;
|
||||
}
|
||||
a:visited {
|
||||
color: #6c71c4;
|
||||
}
|
||||
a:hover {
|
||||
color: #859900;
|
||||
}
|
||||
a:active {
|
||||
color: #2aa198;
|
||||
}
|
||||
a:link { color: #268bd2 }
|
||||
a:visited { color: #6c71c4 }
|
||||
a:hover { color: #859900 }
|
||||
a:active { color: #2aa198 }
|
||||
|
||||
#editor-text-area {
|
||||
background-color: #00000040;
|
||||
color: white;
|
||||
style="flex: 1 1;
|
||||
min-height: 10em;
|
||||
font-size: larger;
|
||||
${this.value?.private ? 'border: 4px solid #800' : ''}
|
||||
</style>
|
||||
<div style="display: inline-flex; flex-direction: row">
|
||||
<button
|
||||
?disabled=${!this.whoami || this.is_editing}
|
||||
@click=${() => (self.is_editing = true)}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
?disabled=${this.blob == this.blob_original}
|
||||
@click=${this.on_save_draft}
|
||||
>
|
||||
Save Draft
|
||||
</button>
|
||||
<button
|
||||
?disabled=${this.blob == this.blob_original && !this.value?.draft}
|
||||
@click=${this.on_publish}
|
||||
>
|
||||
Publish
|
||||
</button>
|
||||
<button ?disabled=${!this.is_editing} @click=${this.on_discard}>
|
||||
Discard
|
||||
</button>
|
||||
<button
|
||||
?disabled=${!this.is_editing}
|
||||
@click=${() =>
|
||||
(self.value = Object.assign({}, self.value, {
|
||||
private: !self.value.private,
|
||||
}))}
|
||||
>
|
||||
${this.value?.private ? 'Make Public' : 'Make Private'}
|
||||
</button>
|
||||
<button ?disabled=${!this.is_editing} @click=${this.on_blog_publish}>
|
||||
Publish Blog
|
||||
</button>
|
||||
<div class="inline-flex-row">
|
||||
<button ?disabled=${!this.whoami || this.is_editing} @click=${() => (self.is_editing = true)}>Edit</button>
|
||||
<button ?disabled=${this.blob == this.blob_original} @click=${this.on_save_draft}>Save Draft</button>
|
||||
<button ?disabled=${this.blob == this.blob_original && !this.value?.draft} @click=${this.on_publish}>Publish</button>
|
||||
<button ?disabled=${!this.is_editing} @click=${this.on_discard}>Discard</button>
|
||||
<button ?disabled=${!this.is_editing} @click=${() => (self.value = Object.assign({}, self.value, {private: !self.value.private}))}>${this.value?.private ? 'Make Public' : 'Make Private'}</button>
|
||||
<button ?disabled=${!this.is_editing} @click=${this.on_blog_publish}>Publish Blog</button>
|
||||
</div>
|
||||
<div ?hidden=${!this.value?.private} style="color: #800">
|
||||
🔒 document is private
|
||||
</div>
|
||||
<div
|
||||
style="display: flex; flex-direction: row; ${this.value?.private
|
||||
? 'border-top: 4px solid #800'
|
||||
: ''}"
|
||||
>
|
||||
<div ?hidden=${!this.value?.private} style="color: #800">🔒 document is private</div>
|
||||
<div class="flex-column" ${this.value?.private ? 'border-top: 4px solid #800' : ''}">
|
||||
<textarea
|
||||
rows="25"
|
||||
?hidden=${!this.is_editing}
|
||||
style="flex: 1 1; min-height: 10em; ${this.value?.private
|
||||
? 'border: 4px solid #800'
|
||||
: ''}"
|
||||
id="editor-text-area"
|
||||
@input=${this.on_edit}
|
||||
@paste=${this.paste}
|
||||
.value=${this.blob ?? ''}
|
||||
></textarea>
|
||||
<div style="flex: 1 1">
|
||||
<div
|
||||
?hidden=${!this.is_editing}
|
||||
style="border: 1px solid #fff; border-radius: 1em; padding: 0.5em"
|
||||
>
|
||||
<img
|
||||
?hidden=${!thumbnail_ref}
|
||||
style="max-width: 128px; max-height: 128px; float: right"
|
||||
src="/${thumbnail_ref}/view"
|
||||
/>
|
||||
<h1 ?hidden=${!this.title(this.blob)}>
|
||||
${unsafeHTML(this.markdown(this.title(this.blob)))}
|
||||
</h1>
|
||||
.value=${this.blob ?? ''}></textarea>
|
||||
<div style="flex: 1 1; margin-top: 16px">
|
||||
<div ?hidden=${!this.is_editing} class="box">
|
||||
Summary
|
||||
<img ?hidden=${!thumbnail_ref} style="max-width: 128px; max-height: 128px; float: right" src="/${thumbnail_ref}/view">
|
||||
<h1 ?hidden=${!this.title(this.blob)}>${unsafeHTML(this.markdown(this.title(this.blob)))}</h1>
|
||||
${unsafeHTML(this.markdown(this.summary(this.blob)))}
|
||||
</div>
|
||||
${unsafeHTML(this.markdown(this.blob))}
|
||||
|
115
apps/wiki/tildefriends.css
Normal file
115
apps/wiki/tildefriends.css
Normal file
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Tilde Friends core stylesheet
|
||||
* This is a prototype; things may change based on feedback.
|
||||
*
|
||||
* This Software is an external library that is part of
|
||||
* Tilde Friends and is shared under the MIT license.
|
||||
*
|
||||
* Inject this file in your app at tildefriends.css
|
||||
* and use this tag to import it:
|
||||
* <link rel="stylesheet" href="tildefriends.css"/>
|
||||
*
|
||||
* Revision 0 / 2024 M02 19
|
||||
*/
|
||||
|
||||
body {
|
||||
color: white;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
button,
|
||||
.button,
|
||||
input[type='button'],
|
||||
input[type='submit'],
|
||||
select {
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
padding: 8px 12px;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
display: inline-block;
|
||||
margin: 4px;
|
||||
|
||||
&.red {
|
||||
background-color: #bd1e24;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.green {
|
||||
background-color: #18922d;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.blue {
|
||||
background-color: #0067a7;
|
||||
color: white;
|
||||
}
|
||||
|
||||
&.yellow {
|
||||
background-color: #ee9600;
|
||||
color: black;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
filter: brightness(0.75);
|
||||
}
|
||||
}
|
||||
|
||||
a:link {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #6c71c4;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #2aa198;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td,
|
||||
th {
|
||||
border: 1px solid #ffffff40;
|
||||
text-align: left;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #ffffff20;
|
||||
}
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.inline-flex-row {
|
||||
display: inline-flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.box {
|
||||
background-color: #00000020;
|
||||
border: 1px solid grey;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
margin: 4px;
|
||||
}
|
BIN
bleh.tar.xz
Normal file
BIN
bleh.tar.xz
Normal file
Binary file not shown.
29
core/app.js
29
core/app.js
@ -6,20 +6,37 @@ let g_calls = {};
|
||||
|
||||
let gSessionIndex = 0;
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function makeSessionId() {
|
||||
return (gSessionIndex++).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function App() {
|
||||
this._on_output = null;
|
||||
this._send_queue = [];
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} callback
|
||||
*/
|
||||
App.prototype.readOutput = function (callback) {
|
||||
this._on_output = callback;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} api
|
||||
* @returns
|
||||
*/
|
||||
App.prototype.makeFunction = function (api) {
|
||||
let self = this;
|
||||
let result = function () {
|
||||
@ -43,6 +60,10 @@ App.prototype.makeFunction = function (api) {
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
*/
|
||||
App.prototype.send = function (message) {
|
||||
if (this._send_queue) {
|
||||
if (this._on_output) {
|
||||
@ -57,11 +78,17 @@ App.prototype.send = function (message) {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} request
|
||||
* @param {*} response
|
||||
* @param {*} client
|
||||
*/
|
||||
function socket(request, response, client) {
|
||||
let process;
|
||||
let options = {};
|
||||
let credentials = auth.query(request.headers);
|
||||
let refresh = auth.make_refresh(credentials);
|
||||
let refresh = auth.makeRefresh(credentials);
|
||||
|
||||
response.onClose = async function () {
|
||||
if (process && process.task) {
|
||||
|
101
core/auth.js
101
core/auth.js
@ -5,9 +5,15 @@ let gDatabase = new Database('auth');
|
||||
|
||||
const kRefreshInterval = 1 * 7 * 24 * 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* Makes a Base64 value URL safe
|
||||
* @param {string} value
|
||||
* @returns TODOC
|
||||
*/
|
||||
function b64url(value) {
|
||||
value = value.replaceAll('+', '-').replaceAll('/', '_');
|
||||
let equals = value.indexOf('=');
|
||||
|
||||
if (equals !== -1) {
|
||||
return value.substring(0, equals);
|
||||
} else {
|
||||
@ -15,9 +21,15 @@ function b64url(value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {string} value
|
||||
* @returns
|
||||
*/
|
||||
function unb64url(value) {
|
||||
value = value.replaceAll('-', '+').replaceAll('_', '/');
|
||||
let remainder = value.length % 4;
|
||||
|
||||
if (remainder == 3) {
|
||||
return value + '=';
|
||||
} else if (remainder == 2) {
|
||||
@ -27,16 +39,22 @@ function unb64url(value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JSON Web Token
|
||||
* @param {object} payload Object: {"name": "username"}
|
||||
* @returns the JWT
|
||||
*/
|
||||
function makeJwt(payload) {
|
||||
let ids = ssb.getIdentities(':auth');
|
||||
const ids = ssb.getIdentities(':auth');
|
||||
let id;
|
||||
|
||||
if (ids?.length) {
|
||||
id = ids[0];
|
||||
} else {
|
||||
id = ssb.createIdentity(':auth');
|
||||
}
|
||||
|
||||
let final_payload = b64url(
|
||||
const final_payload = b64url(
|
||||
base64Encode(
|
||||
JSON.stringify(
|
||||
Object.assign({}, payload, {
|
||||
@ -45,7 +63,7 @@ function makeJwt(payload) {
|
||||
)
|
||||
)
|
||||
);
|
||||
let jwt = [
|
||||
const jwt = [
|
||||
b64url(base64Encode(JSON.stringify({alg: 'HS256', typ: 'JWT'}))),
|
||||
final_payload,
|
||||
b64url(ssb.hmacsha256sign(final_payload, ':auth', id)),
|
||||
@ -53,17 +71,26 @@ function makeJwt(payload) {
|
||||
return jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a JWT ?
|
||||
* @param {*} session TODOC
|
||||
* @returns
|
||||
*/
|
||||
function readSession(session) {
|
||||
let jwt_parts = session?.split('.');
|
||||
|
||||
if (jwt_parts?.length === 3) {
|
||||
let [header, payload, signature] = jwt_parts;
|
||||
header = JSON.parse(utf8Decode(base64Decode(unb64url(header))));
|
||||
|
||||
if (header.typ === 'JWT' && header.alg === 'HS256') {
|
||||
signature = unb64url(signature);
|
||||
let id = ssb.getIdentities(':auth');
|
||||
|
||||
if (id?.length && ssb.hmacsha256verify(id[0], payload, signature)) {
|
||||
let result = JSON.parse(utf8Decode(base64Decode(unb64url(payload))));
|
||||
let now = new Date().valueOf();
|
||||
const result = JSON.parse(utf8Decode(base64Decode(unb64url(payload))));
|
||||
const now = new Date().valueOf();
|
||||
|
||||
if (now < result.exp) {
|
||||
print(`JWT valid for another ${(result.exp - now) / 1000} seconds.`);
|
||||
return result;
|
||||
@ -79,15 +106,30 @@ function readSession(session) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the provided password matches the hash
|
||||
* @param {string} password
|
||||
* @param {string} hash bcrypt hash
|
||||
* @returns true if the password matches the hash
|
||||
*/
|
||||
function verifyPassword(password, hash) {
|
||||
return bCrypt.hashpw(password, hash) == hash;
|
||||
return bCrypt.hashpw(password, hash) === hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes a password
|
||||
* @param {string} password
|
||||
* @returns {string} TODOC
|
||||
*/
|
||||
function hashPassword(password) {
|
||||
let salt = bCrypt.gensalt(12);
|
||||
return bCrypt.hashpw(password, salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there is an administrator on the instance
|
||||
* @returns TODOC
|
||||
*/
|
||||
function noAdministrator() {
|
||||
return (
|
||||
!core.globalSettings ||
|
||||
@ -100,6 +142,10 @@ function noAdministrator() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a user an administrator
|
||||
* @param {string} name the user's name
|
||||
*/
|
||||
function makeAdministrator(name) {
|
||||
if (!core.globalSettings.permissions) {
|
||||
core.globalSettings.permissions = {};
|
||||
@ -110,9 +156,15 @@ function makeAdministrator(name) {
|
||||
if (core.globalSettings.permissions[name].indexOf('administration') == -1) {
|
||||
core.globalSettings.permissions[name].push('administration');
|
||||
}
|
||||
|
||||
core.setGlobalSettings(core.globalSettings);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} headers most likely an object
|
||||
* @returns
|
||||
*/
|
||||
function getCookies(headers) {
|
||||
let cookies = {};
|
||||
|
||||
@ -129,7 +181,13 @@ function getCookies(headers) {
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a username
|
||||
* @param {string} name
|
||||
* @returns false | boolean[] ?
|
||||
*/
|
||||
function isNameValid(name) {
|
||||
// TODO(tasiaiso): convert this into a regex
|
||||
let c = name.charAt(0);
|
||||
return (
|
||||
((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) &&
|
||||
@ -144,7 +202,14 @@ function isNameValid(name) {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request handler ?
|
||||
* @param {*} request TODOC
|
||||
* @param {*} response
|
||||
* @returns
|
||||
*/
|
||||
function handler(request, response) {
|
||||
// TODO(tasiaiso): split this function
|
||||
let session = getCookies(request.headers).session;
|
||||
if (request.uri == '/login') {
|
||||
let formData = form.decodeForm(request.query);
|
||||
@ -285,6 +350,11 @@ function handler(request, response) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a user's permissions based on it's session ?
|
||||
* @param {*} session TODOC
|
||||
* @returns
|
||||
*/
|
||||
function getPermissions(session) {
|
||||
let permissions;
|
||||
let entry = readSession(session);
|
||||
@ -295,6 +365,11 @@ function getPermissions(session) {
|
||||
return permissions || {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a user's permissions ?
|
||||
* @param {string} userName TODOC
|
||||
* @returns
|
||||
*/
|
||||
function getPermissionsForUser(userName) {
|
||||
let permissions = {};
|
||||
if (
|
||||
@ -309,6 +384,11 @@ function getPermissionsForUser(userName) {
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} headers
|
||||
* @returns
|
||||
*/
|
||||
function query(headers) {
|
||||
let session = getCookies(headers).session;
|
||||
let entry;
|
||||
@ -323,7 +403,12 @@ function query(headers) {
|
||||
}
|
||||
}
|
||||
|
||||
function make_refresh(credentials) {
|
||||
/**
|
||||
* Refreshes a JWT ?
|
||||
* @param {*} credentials TODOC
|
||||
* @returns
|
||||
*/
|
||||
function makeRefresh(credentials) {
|
||||
if (credentials?.session?.name) {
|
||||
return {
|
||||
token: makeJwt({name: credentials.session.name}),
|
||||
@ -332,4 +417,4 @@ function make_refresh(credentials) {
|
||||
}
|
||||
}
|
||||
|
||||
export {handler, query, make_refresh};
|
||||
export {handler, query, makeRefresh};
|
||||
|
308
core/client.js
308
core/client.js
@ -12,7 +12,7 @@ let gOriginalInput;
|
||||
let kErrorColor = '#dc322f';
|
||||
let kStatusColor = '#fff';
|
||||
|
||||
/* Functions that server-side app code can call through the app object. */
|
||||
// Functions that server-side app code can call through the app object.
|
||||
const k_api = {
|
||||
setDocument: {args: ['content'], func: api_setDocument},
|
||||
postMessage: {args: ['message'], func: api_postMessage},
|
||||
@ -24,6 +24,7 @@ const k_api = {
|
||||
setHash: {args: ['hash'], func: api_setHash},
|
||||
};
|
||||
|
||||
// TODO(tasiaiso): this is only used once, move it down ?
|
||||
const k_global_style = css`
|
||||
a:link {
|
||||
color: #268bd2;
|
||||
@ -42,6 +43,9 @@ const k_global_style = css`
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* Class that represents the top bar
|
||||
*/
|
||||
class TfNavigationElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
@ -63,6 +67,10 @@ class TfNavigationElement extends LitElement {
|
||||
this.spark_lines = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
*/
|
||||
toggle_edit(event) {
|
||||
event.preventDefault();
|
||||
if (editing()) {
|
||||
@ -72,10 +80,20 @@ class TfNavigationElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
*/
|
||||
reset_permission(key) {
|
||||
send({action: 'resetPermission', permission: key});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param {*} options
|
||||
* @returns
|
||||
*/
|
||||
get_spark_line(key, options) {
|
||||
if (!this.spark_lines[key]) {
|
||||
let spark_line = document.createElement('tf-sparkline');
|
||||
@ -94,6 +112,10 @@ class TfNavigationElement extends LitElement {
|
||||
return this.spark_lines[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render_login() {
|
||||
if (this?.credentials?.session?.name) {
|
||||
return html`<a id="login" href="/login/logout?return=${url() + hash()}"
|
||||
@ -106,6 +128,10 @@ class TfNavigationElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render_permissions() {
|
||||
if (this.show_permissions) {
|
||||
return html`
|
||||
@ -137,13 +163,15 @@ class TfNavigationElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render() {
|
||||
let self = this;
|
||||
return html`
|
||||
<style>
|
||||
/* prettier-ignore */
|
||||
${k_global_style}
|
||||
.tooltip {
|
||||
${k_global_style} .tooltip {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
display: none;
|
||||
@ -230,8 +258,12 @@ class TfNavigationElement extends LitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tf-navigation', TfNavigationElement);
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
class TfFilesElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
@ -247,6 +279,10 @@ class TfFilesElement extends LitElement {
|
||||
this.dropping = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} file
|
||||
*/
|
||||
file_click(file) {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('file_click', {
|
||||
@ -259,6 +295,11 @@ class TfFilesElement extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} file
|
||||
* @returns
|
||||
*/
|
||||
render_file(file) {
|
||||
let classes = ['file'];
|
||||
if (file == this.current) {
|
||||
@ -275,6 +316,10 @@ class TfFilesElement extends LitElement {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
*/
|
||||
async drop(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
@ -296,15 +341,27 @@ class TfFilesElement extends LitElement {
|
||||
updateFiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
*/
|
||||
drag_enter(event) {
|
||||
this.dropping++;
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
*/
|
||||
drag_leave(event) {
|
||||
this.dropping--;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render() {
|
||||
let self = this;
|
||||
return html`
|
||||
@ -350,8 +407,12 @@ class TfFilesElement extends LitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tf-files', TfFilesElement);
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
class TfFilesPaneElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
@ -367,11 +428,19 @@ class TfFilesPaneElement extends LitElement {
|
||||
this.files = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} expanded
|
||||
*/
|
||||
set_expanded(expanded) {
|
||||
this.expanded = expanded;
|
||||
window.localStorage.setItem('files', expanded ? '1' : '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render() {
|
||||
let self = this;
|
||||
let expander = this.expanded
|
||||
@ -425,8 +494,12 @@ class TfFilesPaneElement extends LitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tf-files-pane', TfFilesPaneElement);
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
class TfSparkLineElement extends LitElement {
|
||||
static get properties() {
|
||||
return {
|
||||
@ -444,6 +517,11 @@ class TfSparkLineElement extends LitElement {
|
||||
this.k_values_max = 100;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param {*} value
|
||||
*/
|
||||
append(key, value) {
|
||||
let line = null;
|
||||
for (let it of this.lines) {
|
||||
@ -468,6 +546,11 @@ class TfSparkLineElement extends LitElement {
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} line
|
||||
* @returns
|
||||
*/
|
||||
render_line(line) {
|
||||
if (line?.values?.length >= 2) {
|
||||
let max = Math.max(this.max, ...line.values);
|
||||
@ -481,6 +564,10 @@ class TfSparkLineElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
render() {
|
||||
let max =
|
||||
Math.round(
|
||||
@ -503,8 +590,10 @@ class TfSparkLineElement extends LitElement {
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('tf-sparkline', TfSparkLineElement);
|
||||
|
||||
// TODOC
|
||||
window.addEventListener('keydown', function (event) {
|
||||
if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) {
|
||||
if (editing()) {
|
||||
@ -519,6 +608,12 @@ window.addEventListener('keydown', function (event) {
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} nodes
|
||||
* @param {*} callback
|
||||
* @returns
|
||||
*/
|
||||
function ensureLoaded(nodes, callback) {
|
||||
if (!nodes.length) {
|
||||
callback();
|
||||
@ -559,14 +654,26 @@ function ensureLoaded(nodes, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function editing() {
|
||||
return document.getElementById('editPane').style.display != 'none';
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function is_edit_only() {
|
||||
return window.location.search == '?editonly=1' || window.innerWidth < 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
async function edit() {
|
||||
if (editing()) {
|
||||
return;
|
||||
@ -591,10 +698,18 @@ async function edit() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function trace() {
|
||||
window.open(`/speedscope/#profileURL=${encodeURIComponent('/trace')}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @returns
|
||||
*/
|
||||
function guessMode(name) {
|
||||
return name.endsWith('.js')
|
||||
? 'javascript'
|
||||
@ -603,6 +718,12 @@ function guessMode(name) {
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
function loadFile(name, id) {
|
||||
return fetch('/' + id + '/view')
|
||||
.then(function (response) {
|
||||
@ -626,6 +747,11 @@ function loadFile(name, id) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
* @returns
|
||||
*/
|
||||
async function load(path) {
|
||||
let response = await fetch((path || url()) + 'view');
|
||||
let json;
|
||||
@ -663,16 +789,28 @@ async function load(path) {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function closeEditor() {
|
||||
window.localStorage.setItem('editing', '0');
|
||||
document.getElementById('editPane').style.display = 'none';
|
||||
document.getElementById('viewPane').style.display = 'flex';
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function explodePath() {
|
||||
return /^\/~([^\/]+)\/([^\/]+)(.*)/.exec(window.location.pathname);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} save_to
|
||||
* @returns
|
||||
*/
|
||||
function save(save_to) {
|
||||
document.getElementById('save').disabled = true;
|
||||
if (gCurrentFile) {
|
||||
@ -778,6 +916,9 @@ function save(save_to) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function changeIcon() {
|
||||
let value = prompt('Enter a new app icon emoji:');
|
||||
if (value !== undefined) {
|
||||
@ -786,6 +927,9 @@ function changeIcon() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function deleteApp() {
|
||||
let name = document.getElementById('name');
|
||||
let path = name && name.value ? name.value : url();
|
||||
@ -804,6 +948,10 @@ function deleteApp() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function url() {
|
||||
let hash = window.location.href.indexOf('#');
|
||||
let question = window.location.href.indexOf('?');
|
||||
@ -819,20 +967,36 @@ function url() {
|
||||
: window.location.href;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function hash() {
|
||||
return window.location.hash != '#' ? window.location.hash : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} content
|
||||
*/
|
||||
function api_setDocument(content) {
|
||||
let iframe = document.getElementById('document');
|
||||
iframe.srcdoc = content;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
*/
|
||||
function api_postMessage(message) {
|
||||
let iframe = document.getElementById('document');
|
||||
iframe.contentWindow.postMessage(message, '*');
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} error
|
||||
*/
|
||||
function api_error(error) {
|
||||
if (error) {
|
||||
if (typeof error == 'string') {
|
||||
@ -844,14 +1008,30 @@ function api_error(error) {
|
||||
console.log('error', error);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param {*} value
|
||||
*/
|
||||
function api_localStorageSet(key, value) {
|
||||
window.localStorage.setItem('app:' + key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @returns
|
||||
*/
|
||||
function api_localStorageGet(key) {
|
||||
return window.localStorage.getItem('app:' + key);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} permission
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
function api_requestPermission(permission, id) {
|
||||
let outer = document.createElement('div');
|
||||
outer.classList.add('permissions');
|
||||
@ -917,14 +1097,25 @@ function api_requestPermission(permission, id) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function api_print() {
|
||||
console.log('app>', ...arguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} hash
|
||||
*/
|
||||
function api_setHash(hash) {
|
||||
window.location.hash = hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
*/
|
||||
function _receive_websocket_message(message) {
|
||||
if (message && message.action == 'session') {
|
||||
setStatusMessage('🟢 Executing...', kStatusColor);
|
||||
@ -1011,6 +1202,11 @@ function _receive_websocket_message(message) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* @param {*} color
|
||||
*/
|
||||
function setStatusMessage(message, color) {
|
||||
document.getElementsByTagName('tf-navigation')[0].status = {
|
||||
message: message,
|
||||
@ -1018,6 +1214,10 @@ function setStatusMessage(message, color) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} value
|
||||
*/
|
||||
function send(value) {
|
||||
try {
|
||||
if (gSocket && gSocket.readyState == gSocket.OPEN) {
|
||||
@ -1028,6 +1228,13 @@ function send(value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} sourceData
|
||||
* @param {*} maxWidth
|
||||
* @param {*} maxHeight
|
||||
* @param {*} callback
|
||||
*/
|
||||
function fixImage(sourceData, maxWidth, maxHeight, callback) {
|
||||
let result = sourceData;
|
||||
let image = new Image();
|
||||
@ -1054,16 +1261,26 @@ function fixImage(sourceData, maxWidth, maxHeight, callback) {
|
||||
image.src = sourceData;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} image
|
||||
*/
|
||||
function sendImage(image) {
|
||||
fixImage(image, 320, 240, function (result) {
|
||||
send({image: result});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function hashChange() {
|
||||
send({event: 'hashChange', hash: window.location.hash});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function focus() {
|
||||
if (gSocket && gSocket.readyState == gSocket.CLOSED) {
|
||||
connectSocket();
|
||||
@ -1072,12 +1289,19 @@ function focus() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function blur() {
|
||||
if (gSocket && gSocket.readyState == gSocket.OPEN) {
|
||||
send({event: 'blur'});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
*/
|
||||
function message(event) {
|
||||
if (
|
||||
event.data &&
|
||||
@ -1123,6 +1347,10 @@ function message(event) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
*/
|
||||
function reconnect(path) {
|
||||
let oldSocket = gSocket;
|
||||
gSocket = null;
|
||||
@ -1135,6 +1363,10 @@ function reconnect(path) {
|
||||
connectSocket(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
*/
|
||||
function connectSocket(path) {
|
||||
if (!gSocket || gSocket.readyState != gSocket.OPEN) {
|
||||
if (gSocket) {
|
||||
@ -1194,6 +1426,10 @@ function connectSocket(path) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
*/
|
||||
function openFile(name) {
|
||||
let newDoc =
|
||||
name && gFiles[name]
|
||||
@ -1216,6 +1452,9 @@ function openFile(name) {
|
||||
gEditor.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function updateFiles() {
|
||||
let files = document.getElementsByTagName('tf-files-pane')[0];
|
||||
if (files) {
|
||||
@ -1235,6 +1474,10 @@ function updateFiles() {
|
||||
gEditor.focus();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
*/
|
||||
function makeNewFile(name) {
|
||||
gFiles[name] = {
|
||||
doc: cm6.EditorState.create({extensions: cm6.extensions}),
|
||||
@ -1242,6 +1485,9 @@ function makeNewFile(name) {
|
||||
openFile(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function newFile() {
|
||||
let name = prompt('Name of new file:', 'file.js');
|
||||
if (name && !gFiles[name]) {
|
||||
@ -1249,6 +1495,9 @@ function newFile() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function removeFile() {
|
||||
if (confirm('Remove ' + gCurrentFile + '?')) {
|
||||
delete gFiles[gCurrentFile];
|
||||
@ -1256,6 +1505,9 @@ function removeFile() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
async function appExport() {
|
||||
let JsZip = (await import('/static/jszip.min.js')).default;
|
||||
let owner = window.location.pathname.split('/')[1].replace('~', '');
|
||||
@ -1284,6 +1536,12 @@ async function appExport() {
|
||||
a.click();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @param {*} file
|
||||
* @returns
|
||||
*/
|
||||
async function save_file_to_blob_id(name, file) {
|
||||
console.log(`Saving ${name}.`);
|
||||
let response = await fetch('/save', {
|
||||
@ -1305,6 +1563,9 @@ async function save_file_to_blob_id(name, file) {
|
||||
return blob_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
async function appImport() {
|
||||
let JsZip = (await import('/static/jszip.min.js')).default;
|
||||
let input = document.createElement('input');
|
||||
@ -1373,6 +1634,9 @@ async function appImport() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
async function sourcePretty() {
|
||||
let prettier = (await import('/prettier/standalone.mjs')).default;
|
||||
let babel = (await import('/prettier/babel.mjs')).default;
|
||||
@ -1381,7 +1645,11 @@ async function sourcePretty() {
|
||||
let formatted = await prettier.format(source, {
|
||||
parser: 'babel',
|
||||
plugins: [babel, estree],
|
||||
trailingComma: 'es5',
|
||||
useTabs: true,
|
||||
semi: true,
|
||||
singleQuote: true,
|
||||
bracketSpacing: false,
|
||||
});
|
||||
if (source !== formatted) {
|
||||
gEditor.dispatch({
|
||||
@ -1394,6 +1662,32 @@ async function sourcePretty() {
|
||||
}
|
||||
}
|
||||
|
||||
function toggleVisibleWhitespace() {
|
||||
let editor_style = document.getElementById('editor_style');
|
||||
/*
|
||||
* There is likely a better way to do this, but stomping on the CSS was
|
||||
* the easiest to wrangle at the time.
|
||||
*/
|
||||
if (editor_style.innerHTML.length) {
|
||||
editor_style.innerHTML = '';
|
||||
window.localStorage.setItem('visible_whitespace', '0');
|
||||
} else {
|
||||
editor_style.innerHTML = css`
|
||||
.cm-trailingSpace {
|
||||
background-color: unset !important;
|
||||
}
|
||||
.cm-highlightTab {
|
||||
background-image: unset !important;
|
||||
}
|
||||
.cm-highlightSpace:before {
|
||||
content: unset !important;
|
||||
}
|
||||
`;
|
||||
window.localStorage.setItem('visible_whitespace', '1');
|
||||
}
|
||||
}
|
||||
|
||||
// TODOC
|
||||
window.addEventListener('load', function () {
|
||||
window.addEventListener('hashchange', hashChange);
|
||||
window.addEventListener('focus', focus);
|
||||
@ -1418,6 +1712,9 @@ window.addEventListener('load', function () {
|
||||
document
|
||||
.getElementById('pretty')
|
||||
.addEventListener('click', () => sourcePretty());
|
||||
document
|
||||
.getElementById('whitespace')
|
||||
.addEventListener('click', () => toggleVisibleWhitespace());
|
||||
document
|
||||
.getElementById('trace_button')
|
||||
.addEventListener('click', function (event) {
|
||||
@ -1431,4 +1728,7 @@ window.addEventListener('load', function () {
|
||||
} else {
|
||||
closeEditor();
|
||||
}
|
||||
if (window.localStorage.getItem('visible_whitespace') == '1') {
|
||||
toggleVisibleWhitespace();
|
||||
}
|
||||
});
|
||||
|
233
core/core.js
233
core/core.js
@ -18,20 +18,104 @@ const k_mime_types = {
|
||||
svg: 'image/svg+xml',
|
||||
};
|
||||
|
||||
// prettier-ignore
|
||||
const k_magic_bytes = [
|
||||
{bytes: [0xff, 0xd8, 0xff, 0xdb], type: 'image/jpeg'},
|
||||
{bytes: [0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01], type: 'image/jpeg'},
|
||||
{
|
||||
bytes: [
|
||||
0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01,
|
||||
],
|
||||
type: 'image/jpeg',
|
||||
},
|
||||
{bytes: [0xff, 0xd8, 0xff, 0xee], type: 'image/jpeg'},
|
||||
{bytes: [0xff, 0xd8, 0xff, 0xe1, null, null, 0x45, 0x78, 0x69, 0x66, 0x00, 0x00], type: 'image/jpeg'},
|
||||
{
|
||||
bytes: [
|
||||
0xff,
|
||||
0xd8,
|
||||
0xff,
|
||||
0xe1,
|
||||
null,
|
||||
null,
|
||||
0x45,
|
||||
0x78,
|
||||
0x69,
|
||||
0x66,
|
||||
0x00,
|
||||
0x00,
|
||||
],
|
||||
type: 'image/jpeg',
|
||||
},
|
||||
{bytes: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a], type: 'image/png'},
|
||||
{bytes: [0x47, 0x49, 0x46, 0x38, 0x37, 0x61], type: 'image/gif'},
|
||||
{bytes: [0x47, 0x49, 0x46, 0x38, 0x39, 0x61], type: 'image/gif'},
|
||||
{bytes: [0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50], type: 'image/webp'},
|
||||
{
|
||||
bytes: [
|
||||
0x52,
|
||||
0x49,
|
||||
0x46,
|
||||
0x46,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x57,
|
||||
0x45,
|
||||
0x42,
|
||||
0x50,
|
||||
],
|
||||
type: 'image/webp',
|
||||
},
|
||||
{bytes: [0x3c, 0x73, 0x76, 0x67], type: 'image/svg+xml'},
|
||||
{bytes: [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34, 0x32], type: 'audio/mpeg'},
|
||||
{bytes: [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x69, 0x73, 0x6f, 0x6d], type: 'video/mp4'},
|
||||
{bytes: [null, null, null, null, 0x66, 0x74, 0x79, 0x70, 0x6d, 0x70, 0x34, 0x32], type: 'video/mp4'},
|
||||
{
|
||||
bytes: [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x6d,
|
||||
0x70,
|
||||
0x34,
|
||||
0x32,
|
||||
],
|
||||
type: 'audio/mpeg',
|
||||
},
|
||||
{
|
||||
bytes: [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x69,
|
||||
0x73,
|
||||
0x6f,
|
||||
0x6d,
|
||||
],
|
||||
type: 'video/mp4',
|
||||
},
|
||||
{
|
||||
bytes: [
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
0x66,
|
||||
0x74,
|
||||
0x79,
|
||||
0x70,
|
||||
0x6d,
|
||||
0x70,
|
||||
0x34,
|
||||
0x32,
|
||||
],
|
||||
type: 'video/mp4',
|
||||
},
|
||||
{bytes: [0x4d, 0x54, 0x68, 0x64], type: 'audio/midi'},
|
||||
];
|
||||
|
||||
@ -103,6 +187,11 @@ let gGlobalSettings = {
|
||||
|
||||
let kPingInterval = 60 * 1000;
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} out
|
||||
* @param {*} error
|
||||
*/
|
||||
function printError(out, error) {
|
||||
if (error.stackTrace) {
|
||||
out.print(error.fileName + ':' + error.lineNumber + ': ' + error.message);
|
||||
@ -115,6 +204,12 @@ function printError(out, error) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} handlers
|
||||
* @param {*} argv
|
||||
* @returns
|
||||
*/
|
||||
function invoke(handlers, argv) {
|
||||
let promises = [];
|
||||
if (handlers) {
|
||||
@ -135,6 +230,12 @@ function invoke(handlers, argv) {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} eventName
|
||||
* @param {*} argv
|
||||
* @returns
|
||||
*/
|
||||
function broadcastEvent(eventName, argv) {
|
||||
let promises = [];
|
||||
for (let process of Object.values(gProcesses)) {
|
||||
@ -144,7 +245,11 @@ function broadcastEvent(eventName, argv) {
|
||||
}
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* @returns
|
||||
*/
|
||||
function broadcast(message) {
|
||||
let sender = this;
|
||||
let promises = [];
|
||||
@ -161,6 +266,12 @@ function broadcast(message) {
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} caller
|
||||
* @param {*} process
|
||||
* @returns
|
||||
*/
|
||||
function getUser(caller, process) {
|
||||
return {
|
||||
key: process.key,
|
||||
@ -171,6 +282,12 @@ function getUser(caller, process) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} user
|
||||
* @param {*} process
|
||||
* @returns
|
||||
*/
|
||||
function getApps(user, process) {
|
||||
if (
|
||||
process.credentials &&
|
||||
@ -195,12 +312,26 @@ function getApps(user, process) {
|
||||
return {};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} from
|
||||
* @param {*} to
|
||||
* @param {*} message
|
||||
* @returns
|
||||
*/
|
||||
function postMessageInternal(from, to, message) {
|
||||
if (to.eventHandlers['message']) {
|
||||
return invoke(to.eventHandlers['message'], [getUser(from, from), message]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} blobId
|
||||
* @param {*} session
|
||||
* @param {*} options
|
||||
* @returns
|
||||
*/
|
||||
async function getSessionProcessBlob(blobId, session, options) {
|
||||
let actualOptions = {timeout: kPingInterval};
|
||||
if (options) {
|
||||
@ -211,7 +342,15 @@ async function getSessionProcessBlob(blobId, session, options) {
|
||||
return getProcessBlob(blobId, 'session_' + session, actualOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} blobId
|
||||
* @param {*} key
|
||||
* @param {*} options
|
||||
* @returns
|
||||
*/
|
||||
async function getProcessBlob(blobId, key, options) {
|
||||
// TODO(tasiaiso): break this down ?
|
||||
let process = gProcesses[key];
|
||||
if (!process && !(options && 'create' in options && !options.create)) {
|
||||
let resolveReady;
|
||||
@ -439,6 +578,7 @@ async function getProcessBlob(blobId, key, options) {
|
||||
imports.ssb = Object.fromEntries(
|
||||
Object.keys(ssb).map((key) => [key, ssb[key].bind(ssb)])
|
||||
);
|
||||
imports.ssb.port = tildefriends.ssb_port;
|
||||
imports.ssb.createIdentity = function () {
|
||||
if (
|
||||
process.credentials &&
|
||||
@ -678,6 +818,11 @@ async function getProcessBlob(blobId, key, options) {
|
||||
return process;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} settings
|
||||
* @returns
|
||||
*/
|
||||
function setGlobalSettings(settings) {
|
||||
gGlobalSettings = settings;
|
||||
try {
|
||||
@ -687,6 +832,12 @@ function setGlobalSettings(settings) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} data
|
||||
* @param {*} bytes
|
||||
* @returns
|
||||
*/
|
||||
function startsWithBytes(data, bytes) {
|
||||
if (data.byteLength >= bytes.length) {
|
||||
let dataBytes = new Uint8Array(data.slice(0, bytes.length));
|
||||
@ -699,11 +850,21 @@ function startsWithBytes(data, bytes) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
* @returns
|
||||
*/
|
||||
function guessTypeFromName(path) {
|
||||
let extension = path.split('.').pop();
|
||||
return k_mime_types[extension];
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
function guessTypeFromMagicBytes(data) {
|
||||
for (let magic of k_magic_bytes) {
|
||||
if (startsWithBytes(data, magic.bytes)) {
|
||||
@ -712,6 +873,14 @@ function guessTypeFromMagicBytes(data) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} response
|
||||
* @param {*} data
|
||||
* @param {*} type
|
||||
* @param {*} headers
|
||||
* @param {*} status_code
|
||||
*/
|
||||
function sendData(response, data, type, headers, status_code) {
|
||||
if (data) {
|
||||
response.writeHead(
|
||||
@ -741,6 +910,11 @@ function sendData(response, data, type, headers, status_code) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} id
|
||||
* @returns
|
||||
*/
|
||||
async function getBlobOrContent(id) {
|
||||
if (!id) {
|
||||
return;
|
||||
@ -752,6 +926,18 @@ async function getBlobOrContent(id) {
|
||||
}
|
||||
|
||||
let g_handler_index = 0;
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} response
|
||||
* @param {*} handler_blob_id
|
||||
* @param {*} path
|
||||
* @param {*} query
|
||||
* @param {*} headers
|
||||
* @param {*} packageOwner
|
||||
* @param {*} packageName
|
||||
* @returns
|
||||
*/
|
||||
async function useAppHandler(
|
||||
response,
|
||||
handler_blob_id,
|
||||
@ -797,7 +983,16 @@ async function useAppHandler(
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} request
|
||||
* @param {*} response
|
||||
* @param {*} blobId
|
||||
* @param {*} uri
|
||||
* @returns
|
||||
*/
|
||||
async function blobHandler(request, response, blobId, uri) {
|
||||
// TODO(tasiaiso): break this down ?
|
||||
for (let i in k_static_files) {
|
||||
if (uri === k_static_files[i].uri && k_static_files[i].path) {
|
||||
let stat = await File.stat('core/' + k_static_files[i].path);
|
||||
@ -1079,6 +1274,9 @@ ssb.addEventListener('connections', function () {
|
||||
broadcastEvent('onConnectionsChanged', []);
|
||||
});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
async function loadSettings() {
|
||||
let data = {};
|
||||
try {
|
||||
@ -1097,6 +1295,9 @@ async function loadSettings() {
|
||||
gGlobalSettings = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
function sendStats() {
|
||||
let apps = Object.values(gProcesses)
|
||||
.filter((process) => process.app && process.stats)
|
||||
@ -1112,6 +1313,11 @@ function sendStats() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} process
|
||||
* @param {*} enabled
|
||||
*/
|
||||
function enableStats(process, enabled) {
|
||||
process.stats = enabled;
|
||||
if (!gStatsTimer) {
|
||||
@ -1120,6 +1326,9 @@ function enableStats(process, enabled) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
loadSettings()
|
||||
.then(function () {
|
||||
if (tildefriends.https_port && gGlobalSettings.http_redirect) {
|
||||
@ -1213,6 +1422,14 @@ loadSettings()
|
||||
exit(1);
|
||||
});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} user
|
||||
* @param {*} packageOwner
|
||||
* @param {*} packageName
|
||||
* @param {*} permission
|
||||
* @param {*} allow
|
||||
*/
|
||||
function storePermission(user, packageOwner, packageName, permission, allow) {
|
||||
if (!gGlobalSettings.userPermissions) {
|
||||
gGlobalSettings.userPermissions = {};
|
||||
|
11
core/form.js
11
core/form.js
@ -1,3 +1,8 @@
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} encoded
|
||||
* @returns
|
||||
*/
|
||||
function decode(encoded) {
|
||||
let result = '';
|
||||
for (let i = 0; i < encoded.length; i++) {
|
||||
@ -14,6 +19,12 @@ function decode(encoded) {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} encoded
|
||||
* @param {*} initial
|
||||
* @returns
|
||||
*/
|
||||
function decodeForm(encoded, initial) {
|
||||
let result = initial || {};
|
||||
if (encoded) {
|
||||
|
18
core/http.js
18
core/http.js
@ -1,3 +1,9 @@
|
||||
/**
|
||||
* TODOC
|
||||
* TODO: document so we can improve this
|
||||
* @param {*} url
|
||||
* @returns
|
||||
*/
|
||||
function parseUrl(url) {
|
||||
// XXX: Hack.
|
||||
let match = url.match(new RegExp('(\\w+)://([^/:]+)(?::(\\d+))?(.*)'));
|
||||
@ -9,6 +15,11 @@ function parseUrl(url) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} data
|
||||
* @returns
|
||||
*/
|
||||
function parseResponse(data) {
|
||||
let firstLine;
|
||||
let headers = {};
|
||||
@ -28,6 +39,13 @@ function parseResponse(data) {
|
||||
return {body: data};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} url
|
||||
* @param {*} options
|
||||
* @param {*} allowed_hosts
|
||||
* @returns
|
||||
*/
|
||||
export function fetch(url, options, allowed_hosts) {
|
||||
let parsed = parseUrl(url);
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
@ -57,7 +57,7 @@
|
||||
class="w3-bar-item w3-button w3-blue"
|
||||
id="icon"
|
||||
name="icon"
|
||||
accesskey="i"
|
||||
accesskey="j"
|
||||
onmouseover="set_access_key_title(event)"
|
||||
data-tip="Set an icon/emoji for the app"
|
||||
>
|
||||
@ -93,6 +93,16 @@
|
||||
>
|
||||
🧼
|
||||
</button>
|
||||
<button
|
||||
class="w3-bar-item w3-button w3-blue"
|
||||
id="whitespace"
|
||||
name="whitespace"
|
||||
accesskey="w"
|
||||
onmouseover="set_access_key_title(event)"
|
||||
data-tip="Toggle visible whitespace"
|
||||
>
|
||||
✨
|
||||
</button>
|
||||
<input
|
||||
class="w3-bar-item w3-input w3-border w3-blue"
|
||||
type="text"
|
||||
@ -125,6 +135,7 @@
|
||||
<tf-files-pane style="overflow: auto"></tf-files-pane>
|
||||
</div>
|
||||
<div style="flex: 1 1; overflow: auto">
|
||||
<style id="editor_style"></style>
|
||||
<div id="editor" style="width: 100%; height: 100%"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -3,6 +3,10 @@ let g_api = {};
|
||||
let g_next_id = 1;
|
||||
let g_calls = {};
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @returns
|
||||
*/
|
||||
function get_is_browser() {
|
||||
try {
|
||||
return window !== undefined && console !== undefined;
|
||||
@ -15,6 +19,13 @@ if (k_is_browser) {
|
||||
print = console.log;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} target
|
||||
* @param {*} prop
|
||||
* @param {*} receiver
|
||||
* @returns
|
||||
*/
|
||||
function make_rpc(target, prop, receiver) {
|
||||
return function () {
|
||||
let id = g_next_id++;
|
||||
@ -43,6 +54,10 @@ function make_rpc(target, prop, receiver) {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} response
|
||||
*/
|
||||
function send(response) {
|
||||
if (k_is_browser) {
|
||||
window.parent.postMessage(response, '*');
|
||||
@ -51,6 +66,10 @@ function send(response) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
*/
|
||||
function call_rpc(message) {
|
||||
if (message && message.message === 'tfrpc') {
|
||||
let id = message.id;
|
||||
@ -105,6 +124,10 @@ if (k_is_browser) {
|
||||
|
||||
export let rpc = new Proxy({}, {get: make_rpc});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} method
|
||||
*/
|
||||
export function register(method) {
|
||||
g_api[method.name] = method;
|
||||
}
|
||||
|
36
default.nix
Normal file
36
default.nix
Normal file
@ -0,0 +1,36 @@
|
||||
with import <nixpkgs> {};
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "tildefriends";
|
||||
version = "0.0.16";
|
||||
|
||||
src = fetchurl {
|
||||
url = "https://dev.tildefriends.net/cory/${pname}/archive/v${version}.tar.gz";
|
||||
sha256 = "19iay794xxs3j3mhnpl4vwx65sflw5vvjaahp0jk85wlwlrc7ddw";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
gnumake
|
||||
openssl
|
||||
];
|
||||
# buildInputs = [ ]
|
||||
#doCheck = true;
|
||||
|
||||
|
||||
strictDeps = true;
|
||||
|
||||
outputs = [ "out" ];
|
||||
|
||||
meta = with lib; {
|
||||
#description = "A program that produces a familiar, friendly greeting";
|
||||
#longDescription = ''
|
||||
# GNU Hello is a program that prints "Hello, world!" when you run it.
|
||||
# It is fully customizable.
|
||||
#'';
|
||||
#homepage = "https://www.gnu.org/software/hello/manual/";
|
||||
#changelog = "https://git.savannah.gnu.org/cgit/hello.git/plain/NEWS?h=v${version}";
|
||||
|
||||
license = licenses.gpl3Plus;
|
||||
maintainers = [ maintainers.tasiaiso ];
|
||||
platforms = platforms.all;
|
||||
};
|
||||
}
|
1
deps/codemirror/cm6.js
vendored
1
deps/codemirror/cm6.js
vendored
File diff suppressed because one or more lines are too long
806
deps/codemirror_src/package-lock.json
generated
vendored
Normal file
806
deps/codemirror_src/package-lock.json
generated
vendored
Normal file
@ -0,0 +1,806 @@
|
||||
{
|
||||
"name": "codemirror_src",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "6.2.1",
|
||||
"@codemirror/lang-html": "6.4.8",
|
||||
"@codemirror/lang-javascript": "6.2.2",
|
||||
"@codemirror/lang-json": "6.0.1",
|
||||
"@codemirror/theme-one-dark": "6.1.2",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"codemirror": "6.0.1",
|
||||
"rollup": "4.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-terser": "0.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.15.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.15.0.tgz",
|
||||
"integrity": "sha512-G2Zm0mXznxz97JhaaOdoEG2cVupn4JjPaS4AcNvZzhOsnnG9YVN68VzfoUw6dYTsIxT6a/cmoFEN47KAWhXaOg==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.3.3.tgz",
|
||||
"integrity": "sha512-dO4hcF0fGT9tu1Pj1D2PvGvxjeGkbC6RGcZw6Qs74TH+Ed1gw98jmUgd2axWvIZEqTeTuFrg1lEB1KV6cK9h1A==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.4.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-css": {
|
||||
"version": "6.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.2.1.tgz",
|
||||
"integrity": "sha512-/UNWDNV5Viwi/1lpr/dIXJNWiwDxpw13I4pTUAsNxZdg6E0mI2kTQb0P2iHczg1Tu+H4EBgJR+hYhKiHKko7qg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.0.2",
|
||||
"@lezer/css": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-html": {
|
||||
"version": "6.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.8.tgz",
|
||||
"integrity": "sha512-tE2YK7wDlb9ZpAH6mpTPiYm6rhfdQKVDa5r9IwIFlwwgvVaKsCfuKKZoJGWsmMZIf3FQAuJ5CHMPLymOtg1hXw==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/lang-css": "^6.0.0",
|
||||
"@codemirror/lang-javascript": "^6.0.0",
|
||||
"@codemirror/language": "^6.4.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/css": "^1.1.0",
|
||||
"@lezer/html": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-javascript": {
|
||||
"version": "6.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.2.2.tgz",
|
||||
"integrity": "sha512-VGQfY+FCc285AhWuwjYxQyUQcYurWlxdKYT4bqwr3Twnd5wP5WSeu52t4tvvuWmljT4EmgEgZCqSieokhtY8hg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.6.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/javascript": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-json": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-json/-/lang-json-6.0.1.tgz",
|
||||
"integrity": "sha512-+T1flHdgpqDDlJZ2Lkil/rLiRy684WMLc74xUnjJH48GQdfJo/pudlTRreZmKwzP8/tGdKf83wlbAdOCzlJOGQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@lezer/json": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "6.10.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.10.1.tgz",
|
||||
"integrity": "sha512-5GrXzrhq6k+gL5fjkAwt90nYDmjlzTIJV8THnxNFtNKWotMIlzzN+CpqxqwXOECnUdOndmSeWntVrVcv5axWRQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.23.0",
|
||||
"@lezer/common": "^1.1.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lint": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.5.0.tgz",
|
||||
"integrity": "sha512-+5YyicIaaAZKU8K43IQi8TBy6mF6giGeWAH7N96Z5LC30Wm5JMjqxOYIE9mxwMG1NbhT2mA3l9hA4uuKUM3E5g==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/search": {
|
||||
"version": "6.5.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.5.6.tgz",
|
||||
"integrity": "sha512-rpMgcsh7o0GuCDUXKPvww+muLA1pDJaFrpq/CCHtpQJYz8xopu4D1hPcKRoDD0YlF8gZaqTNIRa4VRBWyhyy7Q==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.4.1.tgz",
|
||||
"integrity": "sha512-QkEyUiLhsJoZkbumGZlswmAhA7CBU02Wrz7zvH4SrcifbsqwlXShVXg65f3v/ts57W3dqyamEriMhij1Z3Zz4A=="
|
||||
},
|
||||
"node_modules/@codemirror/theme-one-dark": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz",
|
||||
"integrity": "sha512-F+sH0X16j/qFLMAfbciKTxVOwkdAS336b7AXTKOZhy8BR3eH/RelsnLgLFINrpST63mmN2OuwUt0W2ndUgYwUA==",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/highlight": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.25.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.25.1.tgz",
|
||||
"integrity": "sha512-2LXLxsQnHDdfGzDvjzAwZh2ZviNJm7im6tGpa0IONIDnFd8RZ80D2SNi8PDi6YjKcMoMRK20v6OmKIdsrwsyoQ==",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.4.0",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.2.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.6",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
|
||||
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.15",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
|
||||
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.25",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.2.1.tgz",
|
||||
"integrity": "sha512-yemX0ZD2xS/73llMZIK6KplkjIjf2EvAHcinDi/TfJ9hS25G0388+ClHt6/3but0oOxinTcQHJLDXh6w1crzFQ=="
|
||||
},
|
||||
"node_modules/@lezer/css": {
|
||||
"version": "1.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.8.tgz",
|
||||
"integrity": "sha512-7JhxupKuMBaWQKjQoLtzhGj83DdnZY9MckEOG5+/iLKNK2ZJqKc6hf6uc0HjwCX7Qlok44jBNqZhHKDhEhZYLA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/highlight": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.0.tgz",
|
||||
"integrity": "sha512-WrS5Mw51sGrpqjlh3d4/fOwpEV2Hd3YOkp9DBt4k8XZQcoTHZFB7sx030A6OcahF4J1nDQAa3jXlTVVYH50IFA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/html": {
|
||||
"version": "1.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.9.tgz",
|
||||
"integrity": "sha512-MXxeCMPyrcemSLGaTQEZx0dBUH0i+RPl8RN5GwMAzo53nTsd/Unc/t5ZxACeQoyPUM5/GkPLRUs2WliOImzkRA==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/javascript": {
|
||||
"version": "1.4.13",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.13.tgz",
|
||||
"integrity": "sha512-5IBr8LIO3xJdJH1e9aj/ZNLE4LSbdsx25wFmGRAZsj2zSmwAYjx26JyU/BYOCpRQlu1jcv1z3vy4NB9+UkfRow==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.1.3",
|
||||
"@lezer/lr": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/json": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/json/-/json-1.0.2.tgz",
|
||||
"integrity": "sha512-xHT2P4S5eeCYECyKNPhr4cbEL9tc8w83SPwRC373o9uEdrvGKTZoJVAGxpOsZckMlEh9W23Pc72ew918RWQOBQ==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/lr": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.0.tgz",
|
||||
"integrity": "sha512-Wst46p51km8gH0ZUmeNrtpRYmdlRHUpN1DQd3GFAyKANi8WVz8c2jHYTf1CVScFaCjQw1iO3ZZdqGDxQPRErTg==",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "15.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz",
|
||||
"integrity": "sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ==",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-builtin-module": "^3.2.1",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-terser": {
|
||||
"version": "0.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.4.4.tgz",
|
||||
"integrity": "sha512-XHeJC5Bgvs8LfukDwWZp7yeqin6ns8RTl2B9avbejt6tZqsqvVoWI7ZTQrcNsfKEDWBTnTxM8nMDkO2IFFbd0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"serialize-javascript": "^6.0.1",
|
||||
"smob": "^1.0.0",
|
||||
"terser": "^5.17.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
|
||||
"integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz",
|
||||
"integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz",
|
||||
"integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz",
|
||||
"integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz",
|
||||
"integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz",
|
||||
"integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz",
|
||||
"integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz",
|
||||
"integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz",
|
||||
"integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz",
|
||||
"integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz",
|
||||
"integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz",
|
||||
"integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz",
|
||||
"integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz",
|
||||
"integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
|
||||
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw=="
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.11.3",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
|
||||
"integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/codemirror": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/search": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g=="
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-builtin-module": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz",
|
||||
"integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==",
|
||||
"dependencies": {
|
||||
"builtin-modules": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.13.1",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
|
||||
"integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
|
||||
"dependencies": {
|
||||
"hasown": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/randombytes": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
|
||||
"integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.8",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz",
|
||||
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.13.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.13.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz",
|
||||
"integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.5"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.13.0",
|
||||
"@rollup/rollup-android-arm64": "4.13.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.13.0",
|
||||
"@rollup/rollup-darwin-x64": "4.13.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.13.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.13.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.13.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.13.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.13.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.13.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.13.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.13.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.13.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/feross"
|
||||
},
|
||||
{
|
||||
"type": "patreon",
|
||||
"url": "https://www.patreon.com/feross"
|
||||
},
|
||||
{
|
||||
"type": "consulting",
|
||||
"url": "https://feross.org/support"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/serialize-javascript": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz",
|
||||
"integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/smob": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/smob/-/smob-1.4.1.tgz",
|
||||
"integrity": "sha512-9LK+E7Hv5R9u4g4C3p+jjLstaLe11MDsL21UpYaCNmapvMkYhqCV4A/f/3gyH8QjMyh6l68q9xC85vihY9ahMQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/style-mod": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.2.tgz",
|
||||
"integrity": "sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw=="
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.29.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.29.1.tgz",
|
||||
"integrity": "sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.8.2",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
"bin": {
|
||||
"terser": "bin/terser"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="
|
||||
}
|
||||
}
|
||||
}
|
21
deps/codemirror_src/package.json
vendored
21
deps/codemirror_src/package.json
vendored
@ -1,15 +1,18 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "rollup --config rollup.config.mjs --input editor.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-css": "^6.2.1",
|
||||
"@codemirror/lang-html": "^6.4.8",
|
||||
"@codemirror/lang-javascript": "^6.2.1",
|
||||
"@codemirror/lang-json": "^6.0.1",
|
||||
"@codemirror/theme-one-dark": "^6.1.2",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"codemirror": "^6.0.1",
|
||||
"rollup": "^4.9.6"
|
||||
"@codemirror/lang-css": "6.2.1",
|
||||
"@codemirror/lang-html": "6.4.8",
|
||||
"@codemirror/lang-javascript": "6.2.2",
|
||||
"@codemirror/lang-json": "6.0.1",
|
||||
"@codemirror/theme-one-dark": "6.1.2",
|
||||
"@rollup/plugin-node-resolve": "15.2.3",
|
||||
"codemirror": "6.0.1",
|
||||
"rollup": "4.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-terser": "^0.4.4"
|
||||
"@rollup/plugin-terser": "0.4.4"
|
||||
}
|
||||
}
|
||||
|
1
deps/crypt_blowfish
vendored
Submodule
1
deps/crypt_blowfish
vendored
Submodule
Submodule deps/crypt_blowfish added at 3354bb81ee
29
deps/crypt_blowfish/LINKS
vendored
29
deps/crypt_blowfish/LINKS
vendored
@ -1,29 +0,0 @@
|
||||
New versions of this package (crypt_blowfish):
|
||||
|
||||
http://www.openwall.com/crypt/
|
||||
|
||||
A paper on the algorithm that explains its design decisions:
|
||||
|
||||
http://www.usenix.org/events/usenix99/provos.html
|
||||
|
||||
Unix Seventh Edition Manual, Volume 2: the password scheme (1978):
|
||||
|
||||
http://plan9.bell-labs.com/7thEdMan/vol2/password
|
||||
|
||||
The Openwall GNU/*/Linux (Owl) tcb suite implementing the alternative
|
||||
password shadowing scheme. This includes a PAM module which
|
||||
supersedes pam_unix and uses the password hashing framework provided
|
||||
with crypt_blowfish when setting new passwords.
|
||||
|
||||
http://www.openwall.com/tcb/
|
||||
|
||||
pam_passwdqc, a password strength checking and policy enforcement
|
||||
module for PAM-aware password changing programs:
|
||||
|
||||
http://www.openwall.com/passwdqc/
|
||||
|
||||
John the Ripper password cracker:
|
||||
|
||||
http://www.openwall.com/john/
|
||||
|
||||
$Owl: Owl/packages/glibc/crypt_blowfish/LINKS,v 1.4 2005/11/16 13:09:47 solar Exp $
|
77
deps/crypt_blowfish/Makefile
vendored
77
deps/crypt_blowfish/Makefile
vendored
@ -1,77 +0,0 @@
|
||||
#
|
||||
# Written and revised by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
# No copyright is claimed, and the software is hereby placed in the public
|
||||
# domain. In case this attempt to disclaim copyright and place the software
|
||||
# in the public domain is deemed null and void, then the software is
|
||||
# Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
# general public under the following terms:
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted.
|
||||
#
|
||||
# There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
#
|
||||
# See crypt_blowfish.c for more information.
|
||||
#
|
||||
|
||||
CC = gcc
|
||||
AS = $(CC)
|
||||
LD = $(CC)
|
||||
RM = rm -f
|
||||
CFLAGS = -W -Wall -Wbad-function-cast -Wcast-align -Wcast-qual -Wmissing-prototypes -Wstrict-prototypes -Wshadow -Wundef -Wpointer-arith -O2 -fomit-frame-pointer -funroll-loops
|
||||
ASFLAGS = -c
|
||||
LDFLAGS = -s
|
||||
|
||||
BLOWFISH_OBJS = \
|
||||
crypt_blowfish.o x86.o
|
||||
|
||||
CRYPT_OBJS = \
|
||||
$(BLOWFISH_OBJS) crypt_gensalt.o wrapper.o
|
||||
|
||||
TEST_OBJS = \
|
||||
$(BLOWFISH_OBJS) crypt_gensalt.o crypt_test.o
|
||||
|
||||
TEST_THREADS_OBJS = \
|
||||
$(BLOWFISH_OBJS) crypt_gensalt.o crypt_test_threads.o
|
||||
|
||||
EXTRA_MANS = \
|
||||
crypt_r.3 crypt_rn.3 crypt_ra.3 \
|
||||
crypt_gensalt.3 crypt_gensalt_rn.3 crypt_gensalt_ra.3
|
||||
|
||||
all: $(CRYPT_OBJS) man
|
||||
|
||||
check: crypt_test
|
||||
./crypt_test
|
||||
|
||||
crypt_test: $(TEST_OBJS)
|
||||
$(LD) $(LDFLAGS) $(TEST_OBJS) -o $@
|
||||
|
||||
crypt_test.o: wrapper.c ow-crypt.h crypt_blowfish.h crypt_gensalt.h
|
||||
$(CC) -c $(CFLAGS) wrapper.c -DTEST -o $@
|
||||
|
||||
check_threads: crypt_test_threads
|
||||
./crypt_test_threads
|
||||
|
||||
crypt_test_threads: $(TEST_THREADS_OBJS)
|
||||
$(LD) $(LDFLAGS) $(TEST_THREADS_OBJS) -lpthread -o $@
|
||||
|
||||
crypt_test_threads.o: wrapper.c ow-crypt.h crypt_blowfish.h crypt_gensalt.h
|
||||
$(CC) -c $(CFLAGS) wrapper.c -DTEST -DTEST_THREADS=4 -o $@
|
||||
|
||||
man: $(EXTRA_MANS)
|
||||
|
||||
$(EXTRA_MANS):
|
||||
echo '.so man3/crypt.3' > $@
|
||||
|
||||
crypt_blowfish.o: crypt_blowfish.h
|
||||
crypt_gensalt.o: crypt_gensalt.h
|
||||
wrapper.o: crypt.h ow-crypt.h crypt_blowfish.h crypt_gensalt.h
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $*.c
|
||||
|
||||
.S.o:
|
||||
$(AS) $(ASFLAGS) $*.S
|
||||
|
||||
clean:
|
||||
$(RM) crypt_test crypt_test_threads *.o $(EXTRA_MANS) core
|
30
deps/crypt_blowfish/PERFORMANCE
vendored
30
deps/crypt_blowfish/PERFORMANCE
vendored
@ -1,30 +0,0 @@
|
||||
These numbers are for 32 iterations ("$2a$05"):
|
||||
|
||||
OpenBSD 3.0 bcrypt(*) crypt_blowfish 0.4.4
|
||||
Pentium III, 840 MHz 99 c/s 121 c/s (+22%)
|
||||
Alpha 21164PC, 533 MHz 55.5 c/s 76.9 c/s (+38%)
|
||||
UltraSparc IIi, 400 MHz 49.9 c/s 52.5 c/s (+5%)
|
||||
Pentium, 120 MHz 8.8 c/s 20.1 c/s (+128%)
|
||||
PA-RISC 7100LC, 80 MHz 8.5 c/s 16.3 c/s (+92%)
|
||||
|
||||
(*) built with -fomit-frame-pointer -funroll-loops, which I don't
|
||||
think happens for libcrypt.
|
||||
|
||||
Starting with version 1.1 released in June 2011, default builds of
|
||||
crypt_blowfish invoke a quick self-test on every hash computation.
|
||||
This has roughly a 4.8% performance impact at "$2a$05", but only a 0.6%
|
||||
impact at a more typical setting of "$2a$08".
|
||||
|
||||
The large speedup for the original Pentium is due to the assembly
|
||||
code and the weird optimizations this processor requires.
|
||||
|
||||
The numbers for password cracking are 2 to 10% higher than those for
|
||||
crypt_blowfish as certain things may be done out of the loop and the
|
||||
code doesn't need to be reentrant.
|
||||
|
||||
Recent versions of John the Ripper (1.6.25-dev and newer) achieve an
|
||||
additional 15% speedup on the Pentium Pro family of processors (which
|
||||
includes Pentium III) with a separate version of the assembly code and
|
||||
run-time CPU detection.
|
||||
|
||||
$Owl: Owl/packages/glibc/crypt_blowfish/PERFORMANCE,v 1.6 2011/06/21 12:09:20 solar Exp $
|
68
deps/crypt_blowfish/README
vendored
68
deps/crypt_blowfish/README
vendored
@ -1,68 +0,0 @@
|
||||
This is an implementation of a password hashing method, provided via the
|
||||
crypt(3) and a reentrant interface. It is fully compatible with
|
||||
OpenBSD's bcrypt.c for prefix "$2b$", originally by Niels Provos and
|
||||
David Mazieres. (Please refer to the included crypt(3) man page for
|
||||
information on minor compatibility issues for other bcrypt prefixes.)
|
||||
|
||||
I've placed this code in the public domain, with fallback to a
|
||||
permissive license. Please see the comment in crypt_blowfish.c for
|
||||
more information.
|
||||
|
||||
You can use the provided routines in your own packages, or link them
|
||||
into a C library. I've provided hooks for linking into GNU libc, but
|
||||
it shouldn't be too hard to get this into another C library. Note
|
||||
that simply adding this code into your libc is probably not enough to
|
||||
make your system use the new password hashing algorithm. Changes to
|
||||
passwd(1), PAM modules, or whatever else your system uses will likely
|
||||
be needed as well. These are not a part of this package, but see
|
||||
LINKS for a pointer to our tcb suite.
|
||||
|
||||
Instructions on using the routines in one of the two common ways are
|
||||
given below. It is recommended that you test the routines on your
|
||||
system before you start. Type "make check" or "make check_threads"
|
||||
(if you have the POSIX threads library), then "make clean".
|
||||
|
||||
|
||||
1. Using the routines in your programs.
|
||||
|
||||
The available interfaces are in ow-crypt.h, and this is the file you
|
||||
should include. You won't need crypt.h. When linking, add all of the
|
||||
C files and x86.S (you can compile and link it even on a non-x86, it
|
||||
will produce no code in this case).
|
||||
|
||||
|
||||
2. Building the routines into GNU C library.
|
||||
|
||||
For versions 2.13 and 2.14 (and likely other nearby ones), extract the
|
||||
library sources as usual. Apply the patch for glibc 2.14 provided in
|
||||
this package. Enter crypt/ and rename crypt.h to gnu-crypt.h within
|
||||
that directory. Copy the C sources, header, and assembly (x86.S) files
|
||||
from this package in there as well (but be sure you don't overwrite the
|
||||
Makefile). Configure, build, and install the library as usual.
|
||||
|
||||
For versions 2.2 to 2.3.6 (and likely also for some newer ones),
|
||||
extract the library sources and maybe its optional add-ons as usual.
|
||||
Apply the patch for glibc 2.3.6 provided in this package. Enter
|
||||
crypt/ and rename crypt.h to gnu-crypt.h within that directory. Copy
|
||||
the C sources, header, and assembly (x86.S) files from this package in
|
||||
there as well (but be sure you don't overwrite the Makefile).
|
||||
Configure, build, and install the library as usual.
|
||||
|
||||
For versions 2.1 to 2.1.3, extract the library sources and the crypt
|
||||
and linuxthreads add-ons as usual. Apply the patch for glibc 2.1.3
|
||||
provided in this package. Enter crypt/sysdeps/unix/, and rename
|
||||
crypt.h to gnu-crypt.h within that directory. Copy C sources, header,
|
||||
and assembly (x86.S) files from this package in there as well (but be
|
||||
sure you don't overwrite the Makefile). Configure, build, and install
|
||||
the library as usual.
|
||||
|
||||
Programs that want to use the provided interfaces will need to include
|
||||
crypt.h (but not ow-crypt.h directly). By default, prototypes for the
|
||||
new routines aren't defined (but the extra functionality of crypt(3)
|
||||
is indeed available). You need to define _OW_SOURCE to obtain the new
|
||||
routines as well.
|
||||
|
||||
--
|
||||
Solar Designer <solar at openwall.com>
|
||||
|
||||
$Owl: Owl/packages/glibc/crypt_blowfish/README,v 1.10 2014/07/07 15:19:04 solar Exp $
|
575
deps/crypt_blowfish/crypt.3
vendored
575
deps/crypt_blowfish/crypt.3
vendored
@ -1,575 +0,0 @@
|
||||
.\" Written and revised by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
.\" No copyright is claimed, and this man page is hereby placed in the public
|
||||
.\" domain. In case this attempt to disclaim copyright and place the man page
|
||||
.\" in the public domain is deemed null and void, then the man page is
|
||||
.\" Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
.\" general public under the following terms:
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted.
|
||||
.\"
|
||||
.\" There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
.\"
|
||||
.\" This manual page in its current form is intended for use on systems
|
||||
.\" based on the GNU C Library with crypt_blowfish patched into libcrypt.
|
||||
.\"
|
||||
.TH CRYPT 3 "July 7, 2014" "Openwall Project" "Library functions"
|
||||
.ad l
|
||||
.\" No macros in NAME to keep makewhatis happy.
|
||||
.SH NAME
|
||||
\fBcrypt\fR, \fBcrypt_r\fR, \fBcrypt_rn\fR, \fBcrypt_ra\fR,
|
||||
\fBcrypt_gensalt\fR, \fBcrypt_gensalt_rn\fR, \fBcrypt_gensalt_ra\fR
|
||||
\- password hashing
|
||||
.SH SYNOPSIS
|
||||
.B #define _XOPEN_SOURCE
|
||||
.br
|
||||
.B #include <unistd.h>
|
||||
.sp
|
||||
.in +8
|
||||
.ti -8
|
||||
.BI "char *crypt(const char *" key ", const char *" setting );
|
||||
.in -8
|
||||
.sp
|
||||
.B #define _GNU_SOURCE
|
||||
.br
|
||||
.B #include <crypt.h>
|
||||
.sp
|
||||
.in +8
|
||||
.ti -8
|
||||
.BI "char *crypt_r(const char *" key ", const char *" setting ", struct crypt_data *" data );
|
||||
.in -8
|
||||
.sp
|
||||
.B #define _OW_SOURCE
|
||||
.br
|
||||
.B #include <crypt.h>
|
||||
.sp
|
||||
.in +8
|
||||
.ti -8
|
||||
.BI "char *crypt_rn(const char *" key ", const char *" setting ", void *" data ", int " size );
|
||||
.ti -8
|
||||
.BI "char *crypt_ra(const char *" key ", const char *" setting ", void **" data ", int *" size );
|
||||
.ti -8
|
||||
.BI "char *crypt_gensalt(const char *" prefix ", unsigned long " count ", const char *" input ", int " size );
|
||||
.ti -8
|
||||
.BI "char *crypt_gensalt_rn(const char *" prefix ", unsigned long " count ", const char *" input ", int " size ", char *" output ", int " output_size );
|
||||
.ti -8
|
||||
.BI "char *crypt_gensalt_ra(const char *" prefix ", unsigned long " count ", const char *" input ", int " size );
|
||||
.ad b
|
||||
.de crypt
|
||||
.BR crypt ,
|
||||
.BR crypt_r ,
|
||||
.BR crypt_rn ", \\$1"
|
||||
.ie "\\$2"" .B crypt_ra
|
||||
.el .BR crypt_ra "\\$2"
|
||||
..
|
||||
.de crypt_gensalt
|
||||
.BR crypt_gensalt ,
|
||||
.BR crypt_gensalt_rn ", \\$1"
|
||||
.ie "\\$2"" .B crypt_gensalt_ra
|
||||
.el .BR crypt_gensalt_ra "\\$2"
|
||||
..
|
||||
.SH DESCRIPTION
|
||||
The
|
||||
.crypt and
|
||||
functions calculate a cryptographic hash function of
|
||||
.I key
|
||||
with one of a number of supported methods as requested with
|
||||
.IR setting ,
|
||||
which is also used to pass a salt and possibly other parameters to
|
||||
the chosen method.
|
||||
The hashing methods are explained below.
|
||||
.PP
|
||||
Unlike
|
||||
.BR crypt ,
|
||||
the functions
|
||||
.BR crypt_r ,
|
||||
.BR crypt_rn " and"
|
||||
.B crypt_ra
|
||||
are reentrant.
|
||||
They place their result and possibly their private data in a
|
||||
.I data
|
||||
area of
|
||||
.I size
|
||||
bytes as passed to them by an application and/or in memory they
|
||||
allocate dynamically. Some hashing algorithms may use the data area to
|
||||
cache precomputed intermediate values across calls. Thus, applications
|
||||
must properly initialize the data area before its first use.
|
||||
.B crypt_r
|
||||
requires that only
|
||||
.I data->initialized
|
||||
be reset to zero;
|
||||
.BR crypt_rn " and " crypt_ra
|
||||
require that either the entire data area is zeroed or, in the case of
|
||||
.BR crypt_ra ,
|
||||
.I *data
|
||||
is NULL. When called with a NULL
|
||||
.I *data
|
||||
or insufficient
|
||||
.I *size
|
||||
for the requested hashing algorithm,
|
||||
.B crypt_ra
|
||||
uses
|
||||
.BR realloc (3)
|
||||
to allocate the required amount of memory dynamically. Thus,
|
||||
.B crypt_ra
|
||||
has the additional requirement that
|
||||
.IR *data ,
|
||||
when non-NULL, must point to an area allocated either with a previous
|
||||
call to
|
||||
.B crypt_ra
|
||||
or with a
|
||||
.BR malloc (3)
|
||||
family call.
|
||||
The memory allocated by
|
||||
.B crypt_ra
|
||||
should be freed with
|
||||
.BR free "(3)."
|
||||
.PP
|
||||
The
|
||||
.crypt_gensalt and
|
||||
functions compile a string for use as
|
||||
.I setting
|
||||
\- with the given
|
||||
.I prefix
|
||||
(used to choose a hashing method), the iteration
|
||||
.I count
|
||||
(if supported by the chosen method) and up to
|
||||
.I size
|
||||
cryptographically random
|
||||
.I input
|
||||
bytes for use as the actual salt.
|
||||
If
|
||||
.I count
|
||||
is 0, a low default will be picked.
|
||||
The random bytes may be obtained from
|
||||
.BR /dev/urandom .
|
||||
Unlike
|
||||
.BR crypt_gensalt ,
|
||||
the functions
|
||||
.BR crypt_gensalt_rn " and " crypt_gensalt_ra
|
||||
are reentrant.
|
||||
.B crypt_gensalt_rn
|
||||
places its result in the
|
||||
.I output
|
||||
buffer of
|
||||
.I output_size
|
||||
bytes.
|
||||
.B crypt_gensalt_ra
|
||||
allocates memory for its result dynamically. The memory should be
|
||||
freed with
|
||||
.BR free "(3)."
|
||||
.SH RETURN VALUE
|
||||
Upon successful completion, the functions
|
||||
.crypt and
|
||||
return a pointer to a string containing the setting that was actually used
|
||||
and a printable encoding of the hash function value.
|
||||
The entire string is directly usable as
|
||||
.I setting
|
||||
with other calls to
|
||||
.crypt and
|
||||
and as
|
||||
.I prefix
|
||||
with calls to
|
||||
.crypt_gensalt and .
|
||||
.PP
|
||||
The behavior of
|
||||
.B crypt
|
||||
on errors isn't well standardized. Some implementations simply can't fail
|
||||
(unless the process dies, in which case they obviously can't return),
|
||||
others return NULL or a fixed string. Most implementations don't set
|
||||
.IR errno ,
|
||||
but some do. SUSv2 specifies only returning NULL and setting
|
||||
.I errno
|
||||
as a valid behavior, and defines only one possible error
|
||||
.RB "(" ENOSYS ,
|
||||
"The functionality is not supported on this implementation.")
|
||||
Unfortunately, most existing applications aren't prepared to handle
|
||||
NULL returns from
|
||||
.BR crypt .
|
||||
The description below corresponds to this implementation of
|
||||
.BR crypt " and " crypt_r
|
||||
only, and to
|
||||
.BR crypt_rn " and " crypt_ra .
|
||||
The behavior may change to match standards, other implementations or
|
||||
existing applications.
|
||||
.PP
|
||||
.BR crypt " and " crypt_r
|
||||
may only fail (and return) when passed an invalid or unsupported
|
||||
.IR setting ,
|
||||
in which case they return a pointer to a magic string that is
|
||||
shorter than 13 characters and is guaranteed to differ from
|
||||
.IR setting .
|
||||
This behavior is safe for older applications which assume that
|
||||
.B crypt
|
||||
can't fail, when both setting new passwords and authenticating against
|
||||
existing password hashes.
|
||||
.BR crypt_rn " and " crypt_ra
|
||||
return NULL to indicate failure. All four functions set
|
||||
.I errno
|
||||
when they fail.
|
||||
.PP
|
||||
The functions
|
||||
.crypt_gensalt and
|
||||
return a pointer to the compiled string for
|
||||
.IR setting ,
|
||||
or NULL on error in which case
|
||||
.I errno
|
||||
is set.
|
||||
.SH ERRORS
|
||||
.TP
|
||||
.B EINVAL
|
||||
.crypt "" :
|
||||
.I setting
|
||||
is invalid or not supported by this implementation;
|
||||
.sp
|
||||
.crypt_gensalt "" :
|
||||
.I prefix
|
||||
is invalid or not supported by this implementation;
|
||||
.I count
|
||||
is invalid for the requested
|
||||
.IR prefix ;
|
||||
the input
|
||||
.I size
|
||||
is insufficient for the smallest valid salt with the requested
|
||||
.IR prefix ;
|
||||
.I input
|
||||
is NULL.
|
||||
.TP
|
||||
.B ERANGE
|
||||
.BR crypt_rn :
|
||||
the provided data area
|
||||
.I size
|
||||
is insufficient for the requested hashing algorithm;
|
||||
.sp
|
||||
.BR crypt_gensalt_rn :
|
||||
.I output_size
|
||||
is too small to hold the compiled
|
||||
.I setting
|
||||
string.
|
||||
.TP
|
||||
.B ENOMEM
|
||||
.B crypt
|
||||
(original glibc only):
|
||||
failed to allocate memory for the output buffer (which subsequent calls
|
||||
would re-use);
|
||||
.sp
|
||||
.BR crypt_ra :
|
||||
.I *data
|
||||
is NULL or
|
||||
.I *size
|
||||
is insufficient for the requested hashing algorithm and
|
||||
.BR realloc (3)
|
||||
failed;
|
||||
.sp
|
||||
.BR crypt_gensalt_ra :
|
||||
failed to allocate memory for the compiled
|
||||
.I setting
|
||||
string.
|
||||
.TP
|
||||
.B ENOSYS
|
||||
.B crypt
|
||||
(SUSv2):
|
||||
the functionality is not supported on this implementation;
|
||||
.sp
|
||||
.BR crypt ,
|
||||
.B crypt_r
|
||||
(glibc 2.0 to 2.0.1 only):
|
||||
.de no-crypt-add-on
|
||||
the crypt add-on is not compiled in and
|
||||
.I setting
|
||||
requests something other than the MD5-based algorithm.
|
||||
..
|
||||
.no-crypt-add-on
|
||||
.TP
|
||||
.B EOPNOTSUPP
|
||||
.BR crypt ,
|
||||
.B crypt_r
|
||||
(glibc 2.0.2 to 2.1.3 only):
|
||||
.no-crypt-add-on
|
||||
.SH HASHING METHODS
|
||||
The implemented hashing methods are intended specifically for processing
|
||||
user passwords for storage and authentication;
|
||||
they are at best inefficient for most other purposes.
|
||||
.PP
|
||||
It is important to understand that password hashing is not a replacement
|
||||
for strong passwords.
|
||||
It is always possible for an attacker with access to password hashes
|
||||
to try guessing candidate passwords against the hashes.
|
||||
There are, however, certain properties a password hashing method may have
|
||||
which make these key search attacks somewhat harder.
|
||||
.PP
|
||||
All of the hashing methods use salts such that the same
|
||||
.I key
|
||||
may produce many possible hashes.
|
||||
Proper use of salts may defeat a number of attacks, including:
|
||||
.TP
|
||||
1.
|
||||
The ability to try candidate passwords against multiple hashes at the
|
||||
price of one.
|
||||
.TP
|
||||
2.
|
||||
The use of pre-hashed lists of candidate passwords.
|
||||
.TP
|
||||
3.
|
||||
The ability to determine whether two users (or two accounts of one user)
|
||||
have the same or different passwords without actually having to guess
|
||||
one of the passwords.
|
||||
.PP
|
||||
The key search attacks depend on computing hashes of large numbers of
|
||||
candidate passwords.
|
||||
Thus, the computational cost of a good password hashing method must be
|
||||
high \- but of course not too high to render it impractical.
|
||||
.PP
|
||||
All hashing methods implemented within the
|
||||
.crypt and
|
||||
interfaces use multiple iterations of an underlying cryptographic
|
||||
primitive specifically in order to increase the cost of trying a
|
||||
candidate password.
|
||||
Unfortunately, due to hardware improvements, the hashing methods which
|
||||
have a fixed cost become increasingly less secure over time.
|
||||
.PP
|
||||
In addition to salts, modern password hashing methods accept a variable
|
||||
iteration
|
||||
.IR count .
|
||||
This makes it possible to adapt their cost to the hardware improvements
|
||||
while still maintaining compatibility.
|
||||
.PP
|
||||
The following hashing methods are or may be implemented within the
|
||||
described interfaces:
|
||||
.PP
|
||||
.de hash
|
||||
.ad l
|
||||
.TP
|
||||
.I prefix
|
||||
.ie "\\$1"" \{\
|
||||
"" (empty string);
|
||||
.br
|
||||
a string matching ^[./0-9A-Za-z]{2} (see
|
||||
.BR regex (7))
|
||||
.\}
|
||||
.el "\\$1"
|
||||
.TP
|
||||
.B Encoding syntax
|
||||
\\$2
|
||||
.TP
|
||||
.B Maximum password length
|
||||
\\$3 (uses \\$4-bit characters)
|
||||
.TP
|
||||
.B Effective key size
|
||||
.ie "\\$5"" limited by the hash size only
|
||||
.el up to \\$5 bits
|
||||
.TP
|
||||
.B Hash size
|
||||
\\$6 bits
|
||||
.TP
|
||||
.B Salt size
|
||||
\\$7 bits
|
||||
.TP
|
||||
.B Iteration count
|
||||
\\$8
|
||||
.ad b
|
||||
..
|
||||
.ti -2
|
||||
.B Traditional DES-based
|
||||
.br
|
||||
This method is supported by almost all implementations of
|
||||
.BR crypt .
|
||||
Unfortunately, it no longer offers adequate security because of its many
|
||||
limitations.
|
||||
Thus, it should not be used for new passwords unless you absolutely have
|
||||
to be able to migrate the password hashes to other systems.
|
||||
.hash "" "[./0-9A-Za-z]{13}" 8 7 56 64 12 25
|
||||
.PP
|
||||
.ti -2
|
||||
.B Extended BSDI-style DES-based
|
||||
.br
|
||||
This method is used on BSDI and is also available on at least NetBSD,
|
||||
OpenBSD, and FreeBSD due to the use of David Burren's FreeSec library.
|
||||
.hash _ "_[./0-9A-Za-z]{19}" unlimited 7 56 64 24 "1 to 2**24-1 (must be odd)"
|
||||
.PP
|
||||
.ti -2
|
||||
.B FreeBSD-style MD5-based
|
||||
.br
|
||||
This is Poul-Henning Kamp's MD5-based password hashing method originally
|
||||
developed for FreeBSD.
|
||||
It is currently supported on many free Unix-like systems, on Solaris 10
|
||||
and newer, and it is part of the official glibc.
|
||||
Its main disadvantage is the fixed iteration count, which is already
|
||||
too low for the currently available hardware.
|
||||
.hash "$1$" "\e$1\e$[^$]{1,8}\e$[./0-9A-Za-z]{22}" unlimited 8 "" 128 "6 to 48" 1000
|
||||
.PP
|
||||
.ti -2
|
||||
.BR "OpenBSD-style Blowfish-based" " (" bcrypt )
|
||||
.br
|
||||
.B bcrypt
|
||||
was originally developed by Niels Provos and David Mazieres for OpenBSD
|
||||
and is also supported on recent versions of FreeBSD and NetBSD,
|
||||
on Solaris 10 and newer, and on several GNU/*/Linux distributions.
|
||||
It is, however, not part of the official glibc.
|
||||
.PP
|
||||
While both
|
||||
.B bcrypt
|
||||
and the BSDI-style DES-based hashing offer a variable iteration count,
|
||||
.B bcrypt
|
||||
may scale to even faster hardware, doesn't allow for certain optimizations
|
||||
specific to password cracking only, doesn't have the effective key size
|
||||
limitation, and uses 8-bit characters in passwords.
|
||||
.hash "$2b$" "\e$2[abxy]\e$[0-9]{2}\e$[./A-Za-z0-9]{53}" 72 8 "" 184 128 "2**4 to 2**99 (current implementations are limited to 2**31 iterations)"
|
||||
.PP
|
||||
With
|
||||
.BR bcrypt ,
|
||||
the
|
||||
.I count
|
||||
passed to
|
||||
.crypt_gensalt and
|
||||
is the base-2 logarithm of the actual iteration count.
|
||||
.PP
|
||||
.B bcrypt
|
||||
hashes used the "$2a$" prefix since 1997.
|
||||
However, in 2011 an implementation bug was discovered in crypt_blowfish
|
||||
(versions up to 1.0.4 inclusive) affecting handling of password characters with
|
||||
the 8th bit set.
|
||||
Besides fixing the bug,
|
||||
to provide for upgrade strategies for existing systems, two new prefixes were
|
||||
introduced: "$2x$", which fully re-introduces the bug, and "$2y$", which
|
||||
guarantees correct handling of both 7- and 8-bit characters.
|
||||
OpenBSD 5.5 introduced the "$2b$" prefix for behavior that exactly matches
|
||||
crypt_blowfish's "$2y$", and current crypt_blowfish supports it as well.
|
||||
Unfortunately, the behavior of "$2a$" on password characters with the 8th bit
|
||||
set has to be considered system-specific.
|
||||
When generating new password hashes, the "$2b$" or "$2y$" prefix should be used.
|
||||
(If such hashes ever need to be migrated to a system that does not yet support
|
||||
these new prefixes, the prefix in migrated copies of the already-generated
|
||||
hashes may be changed to "$2a$".)
|
||||
.PP
|
||||
.crypt_gensalt and
|
||||
support the "$2b$", "$2y$", and "$2a$" prefixes (the latter for legacy programs
|
||||
or configurations), but not "$2x$" (which must not be used for new hashes).
|
||||
.crypt and
|
||||
support all four of these prefixes.
|
||||
.SH PORTABILITY NOTES
|
||||
Programs using any of these functions on a glibc 2.x system must be
|
||||
linked against
|
||||
.BR libcrypt .
|
||||
However, many Unix-like operating systems and older versions of the
|
||||
GNU C Library include the
|
||||
.BR crypt " function in " libc .
|
||||
.PP
|
||||
The
|
||||
.BR crypt_r ,
|
||||
.BR crypt_rn ,
|
||||
.BR crypt_ra ,
|
||||
.crypt_gensalt and
|
||||
functions are very non-portable.
|
||||
.PP
|
||||
The set of supported hashing methods is implementation-dependent.
|
||||
.SH CONFORMING TO
|
||||
The
|
||||
.B crypt
|
||||
function conforms to SVID, X/OPEN, and is available on BSD 4.3.
|
||||
The strings returned by
|
||||
.B crypt
|
||||
are not required to be portable among conformant systems.
|
||||
.PP
|
||||
.B crypt_r
|
||||
is a GNU extension.
|
||||
There's also a
|
||||
.B crypt_r
|
||||
function on HP-UX and MKS Toolkit, but the prototypes and semantics differ.
|
||||
.PP
|
||||
.B crypt_gensalt
|
||||
is an Openwall extension.
|
||||
There's also a
|
||||
.B crypt_gensalt
|
||||
function on Solaris 10 and newer, but the prototypes and semantics differ.
|
||||
.PP
|
||||
.BR crypt_rn ,
|
||||
.BR crypt_ra ,
|
||||
.BR crypt_gensalt_rn ,
|
||||
and
|
||||
.B crypt_gensalt_ra
|
||||
are Openwall extensions.
|
||||
.SH HISTORY
|
||||
A rotor-based
|
||||
.B crypt
|
||||
function appeared in Version 6 AT&T UNIX.
|
||||
The "traditional"
|
||||
.B crypt
|
||||
first appeared in Version 7 AT&T UNIX.
|
||||
.PP
|
||||
The
|
||||
.B crypt_r
|
||||
function was introduced during glibc 2.0 development.
|
||||
.SH BUGS
|
||||
The return values of
|
||||
.BR crypt " and " crypt_gensalt
|
||||
point to static buffers that are overwritten by subsequent calls.
|
||||
These functions are not thread-safe.
|
||||
.RB ( crypt
|
||||
on recent versions of Solaris uses thread-specific data and actually is
|
||||
thread-safe.)
|
||||
.PP
|
||||
The strings returned by certain other implementations of
|
||||
.B crypt
|
||||
on error may be stored in read-only locations or only initialized once,
|
||||
which makes it unsafe to always attempt to zero out the buffer normally
|
||||
pointed to by the
|
||||
.B crypt
|
||||
return value as it would otherwise be preferable for security reasons.
|
||||
The problem could be avoided with the use of
|
||||
.BR crypt_r ,
|
||||
.BR crypt_rn ,
|
||||
or
|
||||
.B crypt_ra
|
||||
where the application has full control over output buffers of these functions
|
||||
(and often over some of their private data as well).
|
||||
Unfortunately, the functions aren't (yet?) available on platforms where
|
||||
.B crypt
|
||||
has this undesired property.
|
||||
.PP
|
||||
Applications using the thread-safe
|
||||
.B crypt_r
|
||||
need to allocate address space for the large (over 128 KB)
|
||||
.I struct crypt_data
|
||||
structure. Each thread needs a separate instance of the structure. The
|
||||
.B crypt_r
|
||||
interface makes it impossible to implement a hashing algorithm which
|
||||
would need to keep an even larger amount of private data, without breaking
|
||||
binary compatibility.
|
||||
.B crypt_ra
|
||||
allows for dynamically increasing the allocation size as required by the
|
||||
hashing algorithm that is actually used. Unfortunately,
|
||||
.B crypt_ra
|
||||
is even more non-portable than
|
||||
.BR crypt_r .
|
||||
.PP
|
||||
Multi-threaded applications or library functions which are meant to be
|
||||
thread-safe should use
|
||||
.BR crypt_gensalt_rn " or " crypt_gensalt_ra
|
||||
rather than
|
||||
.BR crypt_gensalt .
|
||||
.SH SEE ALSO
|
||||
.BR login (1),
|
||||
.BR passwd (1),
|
||||
.BR crypto (3),
|
||||
.BR encrypt (3),
|
||||
.BR free (3),
|
||||
.BR getpass (3),
|
||||
.BR getpwent (3),
|
||||
.BR malloc (3),
|
||||
.BR realloc (3),
|
||||
.BR shadow (3),
|
||||
.BR passwd (5),
|
||||
.BR shadow (5),
|
||||
.BR regex (7),
|
||||
.BR pam (8)
|
||||
.sp
|
||||
Niels Provos and David Mazieres. A Future-Adaptable Password Scheme.
|
||||
Proceedings of the 1999 USENIX Annual Technical Conference, June 1999.
|
||||
.br
|
||||
http://www.usenix.org/events/usenix99/provos.html
|
||||
.sp
|
||||
Robert Morris and Ken Thompson. Password Security: A Case History.
|
||||
Unix Seventh Edition Manual, Volume 2, April 1978.
|
||||
.br
|
||||
http://plan9.bell-labs.com/7thEdMan/vol2/password
|
24
deps/crypt_blowfish/crypt.h
vendored
24
deps/crypt_blowfish/crypt.h
vendored
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2002.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2002 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#include <gnu-crypt.h>
|
||||
|
||||
#if defined(_OW_SOURCE) || defined(__USE_OW)
|
||||
#define __SKIP_GNU
|
||||
#undef __SKIP_OW
|
||||
#include <ow-crypt.h>
|
||||
#undef __SKIP_GNU
|
||||
#endif
|
907
deps/crypt_blowfish/crypt_blowfish.c
vendored
907
deps/crypt_blowfish/crypt_blowfish.c
vendored
@ -1,907 +0,0 @@
|
||||
/*
|
||||
* The crypt_blowfish homepage is:
|
||||
*
|
||||
* http://www.openwall.com/crypt/
|
||||
*
|
||||
* This code comes from John the Ripper password cracker, with reentrant
|
||||
* and crypt(3) interfaces added, but optimizations specific to password
|
||||
* cracking removed.
|
||||
*
|
||||
* Written by Solar Designer <solar at openwall.com> in 1998-2014.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 1998-2014 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* It is my intent that you should be able to use this on your system,
|
||||
* as part of a software package, or anywhere else to improve security,
|
||||
* ensure compatibility, or for any other purpose. I would appreciate
|
||||
* it if you give credit where it is due and keep your modifications in
|
||||
* the public domain as well, but I don't require that in order to let
|
||||
* you place this code and any modifications you make under a license
|
||||
* of your choice.
|
||||
*
|
||||
* This implementation is fully compatible with OpenBSD's bcrypt.c for prefix
|
||||
* "$2b$", originally by Niels Provos <provos at citi.umich.edu>, and it uses
|
||||
* some of his ideas. The password hashing algorithm was designed by David
|
||||
* Mazieres <dm at lcs.mit.edu>. For information on the level of
|
||||
* compatibility for bcrypt hash prefixes other than "$2b$", please refer to
|
||||
* the comments in BF_set_key() below and to the included crypt(3) man page.
|
||||
*
|
||||
* There's a paper on the algorithm that explains its design decisions:
|
||||
*
|
||||
* http://www.usenix.org/events/usenix99/provos.html
|
||||
*
|
||||
* Some of the tricks in BF_ROUND might be inspired by Eric Young's
|
||||
* Blowfish library (I can't be sure if I would think of something if I
|
||||
* hadn't seen his code).
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
/* Just to make sure the prototypes match the actual definitions */
|
||||
#include "crypt_blowfish.h"
|
||||
|
||||
#ifdef __i386__
|
||||
#define BF_ASM 1
|
||||
#define BF_SCALE 1
|
||||
#elif defined(__x86_64__) || defined(__alpha__) || defined(__hppa__)
|
||||
#define BF_ASM 0
|
||||
#define BF_SCALE 1
|
||||
#else
|
||||
#define BF_ASM 0
|
||||
#define BF_SCALE 0
|
||||
#endif
|
||||
|
||||
typedef unsigned int BF_word;
|
||||
typedef signed int BF_word_signed;
|
||||
|
||||
/* Number of Blowfish rounds, this is also hardcoded into a few places */
|
||||
#define BF_N 16
|
||||
|
||||
typedef BF_word BF_key[BF_N + 2];
|
||||
|
||||
typedef struct {
|
||||
BF_word S[4][0x100];
|
||||
BF_key P;
|
||||
} BF_ctx;
|
||||
|
||||
/*
|
||||
* Magic IV for 64 Blowfish encryptions that we do at the end.
|
||||
* The string is "OrpheanBeholderScryDoubt" on big-endian.
|
||||
*/
|
||||
static BF_word BF_magic_w[6] = {
|
||||
0x4F727068, 0x65616E42, 0x65686F6C,
|
||||
0x64657253, 0x63727944, 0x6F756274
|
||||
};
|
||||
|
||||
/*
|
||||
* P-box and S-box tables initialized with digits of Pi.
|
||||
*/
|
||||
static BF_ctx BF_init_state = {
|
||||
{
|
||||
{
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
|
||||
0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
|
||||
0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
|
||||
0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
|
||||
0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
|
||||
0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
|
||||
0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
|
||||
0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
|
||||
0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
|
||||
0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
|
||||
0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
|
||||
0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
|
||||
0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
|
||||
0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
|
||||
0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
|
||||
0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
|
||||
0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
|
||||
0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
|
||||
0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
|
||||
0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
|
||||
0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
|
||||
0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
|
||||
0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
|
||||
0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
|
||||
0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
|
||||
0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
|
||||
0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
|
||||
0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
|
||||
0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
|
||||
0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
|
||||
0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
|
||||
0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
|
||||
0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
|
||||
0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
|
||||
0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
|
||||
0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
|
||||
0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
|
||||
0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
|
||||
0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
|
||||
0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
|
||||
0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
|
||||
0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
|
||||
0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
|
||||
}, {
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
|
||||
0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
||||
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
|
||||
0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
||||
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
|
||||
0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
||||
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
|
||||
0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
||||
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
|
||||
0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
||||
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
|
||||
0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
||||
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
|
||||
0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
||||
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
|
||||
0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
||||
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
|
||||
0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
||||
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
|
||||
0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
||||
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
|
||||
0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
||||
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
|
||||
0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
||||
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
|
||||
0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
||||
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
|
||||
0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
||||
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
|
||||
0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
||||
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
|
||||
0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
||||
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
|
||||
0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
||||
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
|
||||
0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
||||
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
|
||||
0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
||||
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
|
||||
0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
||||
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
|
||||
0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
||||
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
|
||||
}, {
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
||||
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
|
||||
0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
||||
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
|
||||
0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
||||
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
|
||||
0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
||||
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
|
||||
0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
||||
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
|
||||
0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
||||
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
|
||||
0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
||||
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
|
||||
0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
||||
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
|
||||
0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
||||
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
|
||||
0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
||||
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
|
||||
0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
||||
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
|
||||
0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
||||
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
|
||||
0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
||||
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
|
||||
0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
||||
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
|
||||
0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
||||
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
|
||||
0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
||||
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
|
||||
0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
||||
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
|
||||
0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
||||
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
|
||||
0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
||||
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
|
||||
0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
||||
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
|
||||
0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
||||
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
|
||||
0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
|
||||
}, {
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
|
||||
0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
|
||||
0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
|
||||
0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
|
||||
0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
|
||||
0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
|
||||
0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
|
||||
0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
|
||||
0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
|
||||
0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
|
||||
0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
|
||||
0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
|
||||
0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
|
||||
0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
|
||||
0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
|
||||
0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
|
||||
0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
|
||||
0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
|
||||
0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
|
||||
0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
|
||||
0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
|
||||
0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
|
||||
0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
|
||||
0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
|
||||
0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
|
||||
0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
|
||||
0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
|
||||
0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
|
||||
0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
|
||||
0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
|
||||
0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
|
||||
0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
|
||||
0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
|
||||
0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
|
||||
0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
|
||||
0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
|
||||
0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
|
||||
0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
|
||||
0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
|
||||
0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
|
||||
0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
|
||||
0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
|
||||
0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
||||
}
|
||||
}, {
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
|
||||
0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
|
||||
0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
|
||||
0x9216d5d9, 0x8979fb1b
|
||||
}
|
||||
};
|
||||
|
||||
static unsigned char BF_itoa64[64 + 1] =
|
||||
"./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
static unsigned char BF_atoi64[0x60] = {
|
||||
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
|
||||
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
|
||||
64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
|
||||
64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
||||
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
#define BF_safe_atoi64(dst, src) \
|
||||
{ \
|
||||
tmp = (unsigned char)(src); \
|
||||
if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
|
||||
tmp = BF_atoi64[tmp]; \
|
||||
if (tmp > 63) return -1; \
|
||||
(dst) = tmp; \
|
||||
}
|
||||
|
||||
static int BF_decode(BF_word *dst, const char *src, int size)
|
||||
{
|
||||
unsigned char *dptr = (unsigned char *)dst;
|
||||
unsigned char *end = dptr + size;
|
||||
const unsigned char *sptr = (const unsigned char *)src;
|
||||
unsigned int tmp, c1, c2, c3, c4;
|
||||
|
||||
do {
|
||||
BF_safe_atoi64(c1, *sptr++);
|
||||
BF_safe_atoi64(c2, *sptr++);
|
||||
*dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
|
||||
if (dptr >= end) break;
|
||||
|
||||
BF_safe_atoi64(c3, *sptr++);
|
||||
*dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
|
||||
if (dptr >= end) break;
|
||||
|
||||
BF_safe_atoi64(c4, *sptr++);
|
||||
*dptr++ = ((c3 & 0x03) << 6) | c4;
|
||||
} while (dptr < end);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void BF_encode(char *dst, const BF_word *src, int size)
|
||||
{
|
||||
const unsigned char *sptr = (const unsigned char *)src;
|
||||
const unsigned char *end = sptr + size;
|
||||
unsigned char *dptr = (unsigned char *)dst;
|
||||
unsigned int c1, c2;
|
||||
|
||||
do {
|
||||
c1 = *sptr++;
|
||||
*dptr++ = BF_itoa64[c1 >> 2];
|
||||
c1 = (c1 & 0x03) << 4;
|
||||
if (sptr >= end) {
|
||||
*dptr++ = BF_itoa64[c1];
|
||||
break;
|
||||
}
|
||||
|
||||
c2 = *sptr++;
|
||||
c1 |= c2 >> 4;
|
||||
*dptr++ = BF_itoa64[c1];
|
||||
c1 = (c2 & 0x0f) << 2;
|
||||
if (sptr >= end) {
|
||||
*dptr++ = BF_itoa64[c1];
|
||||
break;
|
||||
}
|
||||
|
||||
c2 = *sptr++;
|
||||
c1 |= c2 >> 6;
|
||||
*dptr++ = BF_itoa64[c1];
|
||||
*dptr++ = BF_itoa64[c2 & 0x3f];
|
||||
} while (sptr < end);
|
||||
}
|
||||
|
||||
static void BF_swap(BF_word *x, int count)
|
||||
{
|
||||
static int endianness_check = 1;
|
||||
char *is_little_endian = (char *)&endianness_check;
|
||||
BF_word tmp;
|
||||
|
||||
if (*is_little_endian)
|
||||
do {
|
||||
tmp = *x;
|
||||
tmp = (tmp << 16) | (tmp >> 16);
|
||||
*x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
|
||||
} while (--count);
|
||||
}
|
||||
|
||||
#if BF_SCALE
|
||||
/* Architectures which can shift addresses left by 2 bits with no extra cost */
|
||||
#define BF_ROUND(L, R, N) \
|
||||
tmp1 = L & 0xFF; \
|
||||
tmp2 = L >> 8; \
|
||||
tmp2 &= 0xFF; \
|
||||
tmp3 = L >> 16; \
|
||||
tmp3 &= 0xFF; \
|
||||
tmp4 = L >> 24; \
|
||||
tmp1 = data.ctx.S[3][tmp1]; \
|
||||
tmp2 = data.ctx.S[2][tmp2]; \
|
||||
tmp3 = data.ctx.S[1][tmp3]; \
|
||||
tmp3 += data.ctx.S[0][tmp4]; \
|
||||
tmp3 ^= tmp2; \
|
||||
R ^= data.ctx.P[N + 1]; \
|
||||
tmp3 += tmp1; \
|
||||
R ^= tmp3;
|
||||
#else
|
||||
/* Architectures with no complicated addressing modes supported */
|
||||
#define BF_INDEX(S, i) \
|
||||
(*((BF_word *)(((unsigned char *)S) + (i))))
|
||||
#define BF_ROUND(L, R, N) \
|
||||
tmp1 = L & 0xFF; \
|
||||
tmp1 <<= 2; \
|
||||
tmp2 = L >> 6; \
|
||||
tmp2 &= 0x3FC; \
|
||||
tmp3 = L >> 14; \
|
||||
tmp3 &= 0x3FC; \
|
||||
tmp4 = L >> 22; \
|
||||
tmp4 &= 0x3FC; \
|
||||
tmp1 = BF_INDEX(data.ctx.S[3], tmp1); \
|
||||
tmp2 = BF_INDEX(data.ctx.S[2], tmp2); \
|
||||
tmp3 = BF_INDEX(data.ctx.S[1], tmp3); \
|
||||
tmp3 += BF_INDEX(data.ctx.S[0], tmp4); \
|
||||
tmp3 ^= tmp2; \
|
||||
R ^= data.ctx.P[N + 1]; \
|
||||
tmp3 += tmp1; \
|
||||
R ^= tmp3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Encrypt one block, BF_N is hardcoded here.
|
||||
*/
|
||||
#define BF_ENCRYPT \
|
||||
L ^= data.ctx.P[0]; \
|
||||
BF_ROUND(L, R, 0); \
|
||||
BF_ROUND(R, L, 1); \
|
||||
BF_ROUND(L, R, 2); \
|
||||
BF_ROUND(R, L, 3); \
|
||||
BF_ROUND(L, R, 4); \
|
||||
BF_ROUND(R, L, 5); \
|
||||
BF_ROUND(L, R, 6); \
|
||||
BF_ROUND(R, L, 7); \
|
||||
BF_ROUND(L, R, 8); \
|
||||
BF_ROUND(R, L, 9); \
|
||||
BF_ROUND(L, R, 10); \
|
||||
BF_ROUND(R, L, 11); \
|
||||
BF_ROUND(L, R, 12); \
|
||||
BF_ROUND(R, L, 13); \
|
||||
BF_ROUND(L, R, 14); \
|
||||
BF_ROUND(R, L, 15); \
|
||||
tmp4 = R; \
|
||||
R = L; \
|
||||
L = tmp4 ^ data.ctx.P[BF_N + 1];
|
||||
|
||||
#if BF_ASM
|
||||
#define BF_body() \
|
||||
_BF_body_r(&data.ctx);
|
||||
#else
|
||||
#define BF_body() \
|
||||
L = R = 0; \
|
||||
ptr = data.ctx.P; \
|
||||
do { \
|
||||
ptr += 2; \
|
||||
BF_ENCRYPT; \
|
||||
*(ptr - 2) = L; \
|
||||
*(ptr - 1) = R; \
|
||||
} while (ptr < &data.ctx.P[BF_N + 2]); \
|
||||
\
|
||||
ptr = data.ctx.S[0]; \
|
||||
do { \
|
||||
ptr += 2; \
|
||||
BF_ENCRYPT; \
|
||||
*(ptr - 2) = L; \
|
||||
*(ptr - 1) = R; \
|
||||
} while (ptr < &data.ctx.S[3][0xFF]);
|
||||
#endif
|
||||
|
||||
static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
|
||||
unsigned char flags)
|
||||
{
|
||||
const char *ptr = key;
|
||||
unsigned int bug, i, j;
|
||||
BF_word safety, sign, diff, tmp[2];
|
||||
|
||||
/*
|
||||
* There was a sign extension bug in older revisions of this function. While
|
||||
* we would have liked to simply fix the bug and move on, we have to provide
|
||||
* a backwards compatibility feature (essentially the bug) for some systems and
|
||||
* a safety measure for some others. The latter is needed because for certain
|
||||
* multiple inputs to the buggy algorithm there exist easily found inputs to
|
||||
* the correct algorithm that produce the same hash. Thus, we optionally
|
||||
* deviate from the correct algorithm just enough to avoid such collisions.
|
||||
* While the bug itself affected the majority of passwords containing
|
||||
* characters with the 8th bit set (although only a percentage of those in a
|
||||
* collision-producing way), the anti-collision safety measure affects
|
||||
* only a subset of passwords containing the '\xff' character (not even all of
|
||||
* those passwords, just some of them). This character is not found in valid
|
||||
* UTF-8 sequences and is rarely used in popular 8-bit character encodings.
|
||||
* Thus, the safety measure is unlikely to cause much annoyance, and is a
|
||||
* reasonable tradeoff to use when authenticating against existing hashes that
|
||||
* are not reliably known to have been computed with the correct algorithm.
|
||||
*
|
||||
* We use an approach that tries to minimize side-channel leaks of password
|
||||
* information - that is, we mostly use fixed-cost bitwise operations instead
|
||||
* of branches or table lookups. (One conditional branch based on password
|
||||
* length remains. It is not part of the bug aftermath, though, and is
|
||||
* difficult and possibly unreasonable to avoid given the use of C strings by
|
||||
* the caller, which results in similar timing leaks anyway.)
|
||||
*
|
||||
* For actual implementation, we set an array index in the variable "bug"
|
||||
* (0 means no bug, 1 means sign extension bug emulation) and a flag in the
|
||||
* variable "safety" (bit 16 is set when the safety measure is requested).
|
||||
* Valid combinations of settings are:
|
||||
*
|
||||
* Prefix "$2a$": bug = 0, safety = 0x10000
|
||||
* Prefix "$2b$": bug = 0, safety = 0
|
||||
* Prefix "$2x$": bug = 1, safety = 0
|
||||
* Prefix "$2y$": bug = 0, safety = 0
|
||||
*/
|
||||
bug = (unsigned int)flags & 1;
|
||||
safety = ((BF_word)flags & 2) << 15;
|
||||
|
||||
sign = diff = 0;
|
||||
|
||||
for (i = 0; i < BF_N + 2; i++) {
|
||||
tmp[0] = tmp[1] = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
tmp[0] <<= 8;
|
||||
tmp[0] |= (unsigned char)*ptr; /* correct */
|
||||
tmp[1] <<= 8;
|
||||
tmp[1] |= (BF_word_signed)(signed char)*ptr; /* bug */
|
||||
/*
|
||||
* Sign extension in the first char has no effect - nothing to overwrite yet,
|
||||
* and those extra 24 bits will be fully shifted out of the 32-bit word. For
|
||||
* chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
|
||||
* extension in tmp[1] occurs. Once this flag is set, it remains set.
|
||||
*/
|
||||
if (j)
|
||||
sign |= tmp[1] & 0x80;
|
||||
if (!*ptr)
|
||||
ptr = key;
|
||||
else
|
||||
ptr++;
|
||||
}
|
||||
diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
|
||||
|
||||
expanded[i] = tmp[bug];
|
||||
initial[i] = BF_init_state.P[i] ^ tmp[bug];
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point, "diff" is zero iff the correct and buggy algorithms produced
|
||||
* exactly the same result. If so and if "sign" is non-zero, which indicates
|
||||
* that there was a non-benign sign extension, this means that we have a
|
||||
* collision between the correctly computed hash for this password and a set of
|
||||
* passwords that could be supplied to the buggy algorithm. Our safety measure
|
||||
* is meant to protect from such many-buggy to one-correct collisions, by
|
||||
* deviating from the correct algorithm in such cases. Let's check for this.
|
||||
*/
|
||||
diff |= diff >> 16; /* still zero iff exact match */
|
||||
diff &= 0xffff; /* ditto */
|
||||
diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
|
||||
sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
|
||||
sign &= ~diff & safety; /* action needed? */
|
||||
|
||||
/*
|
||||
* If we have determined that we need to deviate from the correct algorithm,
|
||||
* flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but
|
||||
* let's stick to it now. It came out of the approach we used above, and it's
|
||||
* not any worse than any other choice we could make.)
|
||||
*
|
||||
* It is crucial that we don't do the same to the expanded key used in the main
|
||||
* Eksblowfish loop. By doing it to only one of these two, we deviate from a
|
||||
* state that could be directly specified by a password to the buggy algorithm
|
||||
* (and to the fully correct one as well, but that's a side-effect).
|
||||
*/
|
||||
initial[0] ^= sign;
|
||||
}
|
||||
|
||||
static const unsigned char flags_by_subtype[26] =
|
||||
{2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
|
||||
|
||||
static char *BF_crypt(const char *key, const char *setting,
|
||||
char *output, int size,
|
||||
BF_word min)
|
||||
{
|
||||
#if BF_ASM
|
||||
extern void _BF_body_r(BF_ctx *ctx);
|
||||
#endif
|
||||
struct {
|
||||
BF_ctx ctx;
|
||||
BF_key expanded_key;
|
||||
union {
|
||||
BF_word salt[4];
|
||||
BF_word output[6];
|
||||
} binary;
|
||||
} data;
|
||||
BF_word L, R;
|
||||
BF_word tmp1, tmp2, tmp3, tmp4;
|
||||
BF_word *ptr;
|
||||
BF_word count;
|
||||
int i;
|
||||
|
||||
if (size < 7 + 22 + 31 + 1) {
|
||||
__set_errno(ERANGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (setting[0] != '$' ||
|
||||
setting[1] != '2' ||
|
||||
setting[2] < 'a' || setting[2] > 'z' ||
|
||||
!flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a'] ||
|
||||
setting[3] != '$' ||
|
||||
setting[4] < '0' || setting[4] > '3' ||
|
||||
setting[5] < '0' || setting[5] > '9' ||
|
||||
(setting[4] == '3' && setting[5] > '1') ||
|
||||
setting[6] != '$') {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
|
||||
if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
BF_swap(data.binary.salt, 4);
|
||||
|
||||
BF_set_key(key, data.expanded_key, data.ctx.P,
|
||||
flags_by_subtype[(unsigned int)(unsigned char)setting[2] - 'a']);
|
||||
|
||||
memcpy(data.ctx.S, BF_init_state.S, sizeof(data.ctx.S));
|
||||
|
||||
L = R = 0;
|
||||
for (i = 0; i < BF_N + 2; i += 2) {
|
||||
L ^= data.binary.salt[i & 2];
|
||||
R ^= data.binary.salt[(i & 2) + 1];
|
||||
BF_ENCRYPT;
|
||||
data.ctx.P[i] = L;
|
||||
data.ctx.P[i + 1] = R;
|
||||
}
|
||||
|
||||
ptr = data.ctx.S[0];
|
||||
do {
|
||||
ptr += 4;
|
||||
L ^= data.binary.salt[(BF_N + 2) & 3];
|
||||
R ^= data.binary.salt[(BF_N + 3) & 3];
|
||||
BF_ENCRYPT;
|
||||
*(ptr - 4) = L;
|
||||
*(ptr - 3) = R;
|
||||
|
||||
L ^= data.binary.salt[(BF_N + 4) & 3];
|
||||
R ^= data.binary.salt[(BF_N + 5) & 3];
|
||||
BF_ENCRYPT;
|
||||
*(ptr - 2) = L;
|
||||
*(ptr - 1) = R;
|
||||
} while (ptr < &data.ctx.S[3][0xFF]);
|
||||
|
||||
do {
|
||||
int done;
|
||||
|
||||
for (i = 0; i < BF_N + 2; i += 2) {
|
||||
data.ctx.P[i] ^= data.expanded_key[i];
|
||||
data.ctx.P[i + 1] ^= data.expanded_key[i + 1];
|
||||
}
|
||||
|
||||
done = 0;
|
||||
do {
|
||||
BF_body();
|
||||
if (done)
|
||||
break;
|
||||
done = 1;
|
||||
|
||||
tmp1 = data.binary.salt[0];
|
||||
tmp2 = data.binary.salt[1];
|
||||
tmp3 = data.binary.salt[2];
|
||||
tmp4 = data.binary.salt[3];
|
||||
for (i = 0; i < BF_N; i += 4) {
|
||||
data.ctx.P[i] ^= tmp1;
|
||||
data.ctx.P[i + 1] ^= tmp2;
|
||||
data.ctx.P[i + 2] ^= tmp3;
|
||||
data.ctx.P[i + 3] ^= tmp4;
|
||||
}
|
||||
data.ctx.P[16] ^= tmp1;
|
||||
data.ctx.P[17] ^= tmp2;
|
||||
} while (1);
|
||||
} while (--count);
|
||||
|
||||
for (i = 0; i < 6; i += 2) {
|
||||
L = BF_magic_w[i];
|
||||
R = BF_magic_w[i + 1];
|
||||
|
||||
count = 64;
|
||||
do {
|
||||
BF_ENCRYPT;
|
||||
} while (--count);
|
||||
|
||||
data.binary.output[i] = L;
|
||||
data.binary.output[i + 1] = R;
|
||||
}
|
||||
|
||||
memcpy(output, setting, 7 + 22 - 1);
|
||||
output[7 + 22 - 1] = BF_itoa64[(int)
|
||||
BF_atoi64[(int)setting[7 + 22 - 1] - 0x20] & 0x30];
|
||||
|
||||
/* This has to be bug-compatible with the original implementation, so
|
||||
* only encode 23 of the 24 bytes. :-) */
|
||||
BF_swap(data.binary.output, 6);
|
||||
BF_encode(&output[7 + 22], data.binary.output, 23);
|
||||
output[7 + 22 + 31] = '\0';
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
int _crypt_output_magic(const char *setting, char *output, int size)
|
||||
{
|
||||
if (size < 3)
|
||||
return -1;
|
||||
|
||||
output[0] = '*';
|
||||
output[1] = '0';
|
||||
output[2] = '\0';
|
||||
|
||||
if (setting[0] == '*' && setting[1] == '0')
|
||||
output[1] = '1';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Please preserve the runtime self-test. It serves two purposes at once:
|
||||
*
|
||||
* 1. We really can't afford the risk of producing incompatible hashes e.g.
|
||||
* when there's something like gcc bug 26587 again, whereas an application or
|
||||
* library integrating this code might not also integrate our external tests or
|
||||
* it might not run them after every build. Even if it does, the miscompile
|
||||
* might only occur on the production build, but not on a testing build (such
|
||||
* as because of different optimization settings). It is painful to recover
|
||||
* from incorrectly-computed hashes - merely fixing whatever broke is not
|
||||
* enough. Thus, a proactive measure like this self-test is needed.
|
||||
*
|
||||
* 2. We don't want to leave sensitive data from our actual password hash
|
||||
* computation on the stack or in registers. Previous revisions of the code
|
||||
* would do explicit cleanups, but simply running the self-test after hash
|
||||
* computation is more reliable.
|
||||
*
|
||||
* The performance cost of this quick self-test is around 0.6% at the "$2a$08"
|
||||
* setting.
|
||||
*/
|
||||
char *_crypt_blowfish_rn(const char *key, const char *setting,
|
||||
char *output, int size)
|
||||
{
|
||||
const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
|
||||
const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
|
||||
static const char * const test_hashes[2] =
|
||||
{"i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */
|
||||
"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55"}; /* 'x' */
|
||||
const char *test_hash = test_hashes[0];
|
||||
char *retval;
|
||||
const char *p;
|
||||
int save_errno, ok;
|
||||
struct {
|
||||
char s[7 + 22 + 1];
|
||||
char o[7 + 22 + 31 + 1 + 1 + 1];
|
||||
} buf;
|
||||
|
||||
/* Hash the supplied password */
|
||||
_crypt_output_magic(setting, output, size);
|
||||
retval = BF_crypt(key, setting, output, size, 16);
|
||||
save_errno = errno;
|
||||
|
||||
/*
|
||||
* Do a quick self-test. It is important that we make both calls to BF_crypt()
|
||||
* from the same scope such that they likely use the same stack locations,
|
||||
* which makes the second call overwrite the first call's sensitive data on the
|
||||
* stack and makes it more likely that any alignment related issues would be
|
||||
* detected by the self-test.
|
||||
*/
|
||||
memcpy(buf.s, test_setting, sizeof(buf.s));
|
||||
if (retval) {
|
||||
unsigned int flags = flags_by_subtype[
|
||||
(unsigned int)(unsigned char)setting[2] - 'a'];
|
||||
test_hash = test_hashes[flags & 1];
|
||||
buf.s[2] = setting[2];
|
||||
}
|
||||
memset(buf.o, 0x55, sizeof(buf.o));
|
||||
buf.o[sizeof(buf.o) - 1] = 0;
|
||||
p = BF_crypt(test_key, buf.s, buf.o, sizeof(buf.o) - (1 + 1), 1);
|
||||
|
||||
ok = (p == buf.o &&
|
||||
!memcmp(p, buf.s, 7 + 22) &&
|
||||
!memcmp(p + (7 + 22), test_hash, 31 + 1 + 1 + 1));
|
||||
|
||||
{
|
||||
const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
|
||||
BF_key ae, ai, ye, yi;
|
||||
BF_set_key(k, ae, ai, 2); /* $2a$ */
|
||||
BF_set_key(k, ye, yi, 4); /* $2y$ */
|
||||
ai[0] ^= 0x10000; /* undo the safety (for comparison) */
|
||||
ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
|
||||
!memcmp(ae, ye, sizeof(ae)) &&
|
||||
!memcmp(ai, yi, sizeof(ai));
|
||||
}
|
||||
|
||||
__set_errno(save_errno);
|
||||
if (ok)
|
||||
return retval;
|
||||
|
||||
/* Should not happen */
|
||||
_crypt_output_magic(setting, output, size);
|
||||
__set_errno(EINVAL); /* pretend we don't support this hash type */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
if (size < 16 || output_size < 7 + 22 + 1 ||
|
||||
(count && (count < 4 || count > 31)) ||
|
||||
prefix[0] != '$' || prefix[1] != '2' ||
|
||||
(prefix[2] != 'a' && prefix[2] != 'b' && prefix[2] != 'y')) {
|
||||
if (output_size > 0) output[0] = '\0';
|
||||
__set_errno((output_size < 7 + 22 + 1) ? ERANGE : EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!count) count = 5;
|
||||
|
||||
output[0] = '$';
|
||||
output[1] = '2';
|
||||
output[2] = prefix[2];
|
||||
output[3] = '$';
|
||||
output[4] = '0' + count / 10;
|
||||
output[5] = '0' + count % 10;
|
||||
output[6] = '$';
|
||||
|
||||
BF_encode(&output[7], (const BF_word *)input, 16);
|
||||
output[7 + 22] = '\0';
|
||||
|
||||
return output;
|
||||
}
|
27
deps/crypt_blowfish/crypt_blowfish.h
vendored
27
deps/crypt_blowfish/crypt_blowfish.h
vendored
@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPT_BLOWFISH_H
|
||||
#define _CRYPT_BLOWFISH_H
|
||||
|
||||
extern int _crypt_output_magic(const char *setting, char *output, int size);
|
||||
extern char *_crypt_blowfish_rn(const char *key, const char *setting,
|
||||
char *output, int size);
|
||||
extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
|
||||
unsigned long count,
|
||||
const char *input, int size, char *output, int output_size);
|
||||
|
||||
#endif
|
124
deps/crypt_blowfish/crypt_gensalt.c
vendored
124
deps/crypt_blowfish/crypt_gensalt.c
vendored
@ -1,124 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*
|
||||
* This file contains salt generation functions for the traditional and
|
||||
* other common crypt(3) algorithms, except for bcrypt which is defined
|
||||
* entirely in crypt_blowfish.c.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
/* Just to make sure the prototypes match the actual definitions */
|
||||
#include "crypt_gensalt.h"
|
||||
|
||||
unsigned char _crypt_itoa64[64 + 1] =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
char *_crypt_gensalt_traditional_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
(void) prefix;
|
||||
|
||||
if (size < 2 || output_size < 2 + 1 || (count && count != 25)) {
|
||||
if (output_size > 0) output[0] = '\0';
|
||||
__set_errno((output_size < 2 + 1) ? ERANGE : EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
output[0] = _crypt_itoa64[(unsigned int)input[0] & 0x3f];
|
||||
output[1] = _crypt_itoa64[(unsigned int)input[1] & 0x3f];
|
||||
output[2] = '\0';
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
char *_crypt_gensalt_extended_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
(void) prefix;
|
||||
|
||||
/* Even iteration counts make it easier to detect weak DES keys from a look
|
||||
* at the hash, so they should be avoided */
|
||||
if (size < 3 || output_size < 1 + 4 + 4 + 1 ||
|
||||
(count && (count > 0xffffff || !(count & 1)))) {
|
||||
if (output_size > 0) output[0] = '\0';
|
||||
__set_errno((output_size < 1 + 4 + 4 + 1) ? ERANGE : EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!count) count = 725;
|
||||
|
||||
output[0] = '_';
|
||||
output[1] = _crypt_itoa64[count & 0x3f];
|
||||
output[2] = _crypt_itoa64[(count >> 6) & 0x3f];
|
||||
output[3] = _crypt_itoa64[(count >> 12) & 0x3f];
|
||||
output[4] = _crypt_itoa64[(count >> 18) & 0x3f];
|
||||
value = (unsigned long)(unsigned char)input[0] |
|
||||
((unsigned long)(unsigned char)input[1] << 8) |
|
||||
((unsigned long)(unsigned char)input[2] << 16);
|
||||
output[5] = _crypt_itoa64[value & 0x3f];
|
||||
output[6] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[7] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
output[8] = _crypt_itoa64[(value >> 18) & 0x3f];
|
||||
output[9] = '\0';
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
unsigned long value;
|
||||
|
||||
(void) prefix;
|
||||
|
||||
if (size < 3 || output_size < 3 + 4 + 1 || (count && count != 1000)) {
|
||||
if (output_size > 0) output[0] = '\0';
|
||||
__set_errno((output_size < 3 + 4 + 1) ? ERANGE : EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
output[0] = '$';
|
||||
output[1] = '1';
|
||||
output[2] = '$';
|
||||
value = (unsigned long)(unsigned char)input[0] |
|
||||
((unsigned long)(unsigned char)input[1] << 8) |
|
||||
((unsigned long)(unsigned char)input[2] << 16);
|
||||
output[3] = _crypt_itoa64[value & 0x3f];
|
||||
output[4] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[5] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
output[6] = _crypt_itoa64[(value >> 18) & 0x3f];
|
||||
output[7] = '\0';
|
||||
|
||||
if (size >= 6 && output_size >= 3 + 4 + 4 + 1) {
|
||||
value = (unsigned long)(unsigned char)input[3] |
|
||||
((unsigned long)(unsigned char)input[4] << 8) |
|
||||
((unsigned long)(unsigned char)input[5] << 16);
|
||||
output[7] = _crypt_itoa64[value & 0x3f];
|
||||
output[8] = _crypt_itoa64[(value >> 6) & 0x3f];
|
||||
output[9] = _crypt_itoa64[(value >> 12) & 0x3f];
|
||||
output[10] = _crypt_itoa64[(value >> 18) & 0x3f];
|
||||
output[11] = '\0';
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
30
deps/crypt_blowfish/crypt_gensalt.h
vendored
30
deps/crypt_blowfish/crypt_gensalt.h
vendored
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPT_GENSALT_H
|
||||
#define _CRYPT_GENSALT_H
|
||||
|
||||
extern unsigned char _crypt_itoa64[];
|
||||
extern char *_crypt_gensalt_traditional_rn(const char *prefix,
|
||||
unsigned long count,
|
||||
const char *input, int size, char *output, int output_size);
|
||||
extern char *_crypt_gensalt_extended_rn(const char *prefix,
|
||||
unsigned long count,
|
||||
const char *input, int size, char *output, int output_size);
|
||||
extern char *_crypt_gensalt_md5_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size);
|
||||
|
||||
#endif
|
53
deps/crypt_blowfish/glibc-2.1.3-crypt.diff
vendored
53
deps/crypt_blowfish/glibc-2.1.3-crypt.diff
vendored
@ -1,53 +0,0 @@
|
||||
--- glibc-2.1.3.orig/crypt/sysdeps/unix/Makefile 1997-03-05 00:33:59 +0000
|
||||
+++ glibc-2.1.3/crypt/sysdeps/unix/Makefile 2000-06-11 03:13:41 +0000
|
||||
@@ -1,4 +1,4 @@
|
||||
ifeq ($(subdir),md5-crypt)
|
||||
-libcrypt-routines += crypt crypt_util
|
||||
-dont_distribute += crypt.c crypt_util.c
|
||||
+libcrypt-routines += crypt crypt_util crypt_blowfish x86 crypt_gensalt wrapper
|
||||
+dont_distribute += crypt.c crypt_util.c crypt_blowfish.c x86.S crypt_gensalt.c wrapper.c
|
||||
endif
|
||||
--- glibc-2.1.3.orig/crypt/sysdeps/unix/crypt-entry.c 1998-12-10 12:49:04 +0000
|
||||
+++ glibc-2.1.3/crypt/sysdeps/unix/crypt-entry.c 2000-06-11 03:14:57 +0000
|
||||
@@ -70,7 +70,7 @@ extern struct crypt_data _ufc_foobar;
|
||||
*/
|
||||
|
||||
char *
|
||||
-__crypt_r (key, salt, data)
|
||||
+__des_crypt_r (key, salt, data)
|
||||
const char *key;
|
||||
const char *salt;
|
||||
struct crypt_data * __restrict data;
|
||||
@@ -115,6 +115,7 @@ __crypt_r (key, salt, data)
|
||||
_ufc_output_conversion_r (res[0], res[1], salt, data);
|
||||
return data->crypt_3_buf;
|
||||
}
|
||||
+#if 0
|
||||
weak_alias (__crypt_r, crypt_r)
|
||||
|
||||
char *
|
||||
@@ -147,3 +148,4 @@ __fcrypt (key, salt)
|
||||
return crypt (key, salt);
|
||||
}
|
||||
#endif
|
||||
+#endif
|
||||
--- glibc-2.1.3.orig/md5-crypt/Makefile 1998-07-02 22:46:47 +0000
|
||||
+++ glibc-2.1.3/md5-crypt/Makefile 2000-06-11 03:12:34 +0000
|
||||
@@ -21,7 +21,7 @@
|
||||
#
|
||||
subdir := md5-crypt
|
||||
|
||||
-headers := crypt.h
|
||||
+headers := crypt.h gnu-crypt.h ow-crypt.h
|
||||
|
||||
distribute := md5.h
|
||||
|
||||
--- glibc-2.1.3.orig/md5-crypt/Versions 1998-07-02 22:32:07 +0000
|
||||
+++ glibc-2.1.3/md5-crypt/Versions 2000-06-11 09:11:03 +0000
|
||||
@@ -1,5 +1,6 @@
|
||||
libcrypt {
|
||||
GLIBC_2.0 {
|
||||
crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
|
||||
+ crypt_rn; crypt_ra; crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra;
|
||||
}
|
||||
}
|
55
deps/crypt_blowfish/glibc-2.14-crypt.diff
vendored
55
deps/crypt_blowfish/glibc-2.14-crypt.diff
vendored
@ -1,55 +0,0 @@
|
||||
diff -urp glibc-2.14.orig/crypt/Makefile glibc-2.14/crypt/Makefile
|
||||
--- glibc-2.14.orig/crypt/Makefile 2011-05-31 04:12:33 +0000
|
||||
+++ glibc-2.14/crypt/Makefile 2011-07-16 21:40:56 +0000
|
||||
@@ -22,6 +22,7 @@
|
||||
subdir := crypt
|
||||
|
||||
headers := crypt.h
|
||||
+headers += gnu-crypt.h ow-crypt.h
|
||||
|
||||
extra-libs := libcrypt
|
||||
extra-libs-others := $(extra-libs)
|
||||
@@ -29,6 +30,8 @@ extra-libs-others := $(extra-libs)
|
||||
libcrypt-routines := crypt-entry md5-crypt sha256-crypt sha512-crypt crypt \
|
||||
crypt_util
|
||||
|
||||
+libcrypt-routines += crypt_blowfish x86 crypt_gensalt wrapper
|
||||
+
|
||||
tests := cert md5c-test sha256c-test sha512c-test
|
||||
|
||||
distribute := ufc-crypt.h crypt-private.h ufc.c speeds.c README.ufc-crypt \
|
||||
diff -urp glibc-2.14.orig/crypt/Versions glibc-2.14/crypt/Versions
|
||||
--- glibc-2.14.orig/crypt/Versions 2011-05-31 04:12:33 +0000
|
||||
+++ glibc-2.14/crypt/Versions 2011-07-16 21:40:56 +0000
|
||||
@@ -1,5 +1,6 @@
|
||||
libcrypt {
|
||||
GLIBC_2.0 {
|
||||
crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
|
||||
+ crypt_rn; crypt_ra; crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra;
|
||||
}
|
||||
}
|
||||
diff -urp glibc-2.14.orig/crypt/crypt-entry.c glibc-2.14/crypt/crypt-entry.c
|
||||
--- glibc-2.14.orig/crypt/crypt-entry.c 2011-05-31 04:12:33 +0000
|
||||
+++ glibc-2.14/crypt/crypt-entry.c 2011-07-16 21:40:56 +0000
|
||||
@@ -82,7 +82,7 @@ extern struct crypt_data _ufc_foobar;
|
||||
*/
|
||||
|
||||
char *
|
||||
-__crypt_r (key, salt, data)
|
||||
+__des_crypt_r (key, salt, data)
|
||||
const char *key;
|
||||
const char *salt;
|
||||
struct crypt_data * __restrict data;
|
||||
@@ -137,6 +137,7 @@ __crypt_r (key, salt, data)
|
||||
_ufc_output_conversion_r (res[0], res[1], salt, data);
|
||||
return data->crypt_3_buf;
|
||||
}
|
||||
+#if 0
|
||||
weak_alias (__crypt_r, crypt_r)
|
||||
|
||||
char *
|
||||
@@ -177,3 +178,4 @@ __fcrypt (key, salt)
|
||||
return crypt (key, salt);
|
||||
}
|
||||
#endif
|
||||
+#endif
|
52
deps/crypt_blowfish/glibc-2.3.6-crypt.diff
vendored
52
deps/crypt_blowfish/glibc-2.3.6-crypt.diff
vendored
@ -1,52 +0,0 @@
|
||||
--- glibc-2.3.6.orig/crypt/Makefile 2001-07-06 04:54:45 +0000
|
||||
+++ glibc-2.3.6/crypt/Makefile 2004-02-27 00:23:48 +0000
|
||||
@@ -21,14 +21,14 @@
|
||||
#
|
||||
subdir := crypt
|
||||
|
||||
-headers := crypt.h
|
||||
+headers := crypt.h gnu-crypt.h ow-crypt.h
|
||||
|
||||
distribute := md5.h
|
||||
|
||||
extra-libs := libcrypt
|
||||
extra-libs-others := $(extra-libs)
|
||||
|
||||
-libcrypt-routines := crypt-entry md5-crypt md5 crypt crypt_util
|
||||
+libcrypt-routines := crypt-entry md5-crypt md5 crypt crypt_util crypt_blowfish x86 crypt_gensalt wrapper
|
||||
|
||||
tests = cert md5test md5c-test
|
||||
|
||||
--- glibc-2.3.6.orig/crypt/Versions 2000-03-04 00:47:30 +0000
|
||||
+++ glibc-2.3.6/crypt/Versions 2004-02-27 00:25:15 +0000
|
||||
@@ -1,5 +1,6 @@
|
||||
libcrypt {
|
||||
GLIBC_2.0 {
|
||||
crypt; crypt_r; encrypt; encrypt_r; fcrypt; setkey; setkey_r;
|
||||
+ crypt_rn; crypt_ra; crypt_gensalt; crypt_gensalt_rn; crypt_gensalt_ra;
|
||||
}
|
||||
}
|
||||
--- glibc-2.3.6.orig/crypt/crypt-entry.c 2001-07-06 05:18:49 +0000
|
||||
+++ glibc-2.3.6/crypt/crypt-entry.c 2004-02-27 00:12:32 +0000
|
||||
@@ -70,7 +70,7 @@ extern struct crypt_data _ufc_foobar;
|
||||
*/
|
||||
|
||||
char *
|
||||
-__crypt_r (key, salt, data)
|
||||
+__des_crypt_r (key, salt, data)
|
||||
const char *key;
|
||||
const char *salt;
|
||||
struct crypt_data * __restrict data;
|
||||
@@ -115,6 +115,7 @@ __crypt_r (key, salt, data)
|
||||
_ufc_output_conversion_r (res[0], res[1], salt, data);
|
||||
return data->crypt_3_buf;
|
||||
}
|
||||
+#if 0
|
||||
weak_alias (__crypt_r, crypt_r)
|
||||
|
||||
char *
|
||||
@@ -147,3 +148,4 @@ __fcrypt (key, salt)
|
||||
return crypt (key, salt);
|
||||
}
|
||||
#endif
|
||||
+#endif
|
43
deps/crypt_blowfish/ow-crypt.h
vendored
43
deps/crypt_blowfish/ow-crypt.h
vendored
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2011.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2011 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#ifndef _OW_CRYPT_H
|
||||
#define _OW_CRYPT_H
|
||||
|
||||
#ifndef __GNUC__
|
||||
#undef __const
|
||||
#define __const const
|
||||
#endif
|
||||
|
||||
#ifndef __SKIP_GNU
|
||||
extern char *crypt(__const char *key, __const char *setting);
|
||||
extern char *crypt_r(__const char *key, __const char *setting, void *data);
|
||||
#endif
|
||||
|
||||
#ifndef __SKIP_OW
|
||||
extern char *crypt_rn(__const char *key, __const char *setting,
|
||||
void *data, int size);
|
||||
extern char *crypt_ra(__const char *key, __const char *setting,
|
||||
void **data, int *size);
|
||||
extern char *crypt_gensalt(__const char *prefix, unsigned long count,
|
||||
__const char *input, int size);
|
||||
extern char *crypt_gensalt_rn(__const char *prefix, unsigned long count,
|
||||
__const char *input, int size, char *output, int output_size);
|
||||
extern char *crypt_gensalt_ra(__const char *prefix, unsigned long count,
|
||||
__const char *input, int size);
|
||||
#endif
|
||||
|
||||
#endif
|
551
deps/crypt_blowfish/wrapper.c
vendored
551
deps/crypt_blowfish/wrapper.c
vendored
@ -1,551 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 2000-2014.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 2000-2014 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <errno.h>
|
||||
#ifndef __set_errno
|
||||
#define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/times.h>
|
||||
#ifdef TEST_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define CRYPT_OUTPUT_SIZE (7 + 22 + 31 + 1)
|
||||
#define CRYPT_GENSALT_OUTPUT_SIZE (7 + 22 + 1)
|
||||
|
||||
#if defined(__GLIBC__) && defined(_LIBC)
|
||||
#define __SKIP_GNU
|
||||
#endif
|
||||
#include "ow-crypt.h"
|
||||
|
||||
#include "crypt_blowfish.h"
|
||||
#include "crypt_gensalt.h"
|
||||
|
||||
#if defined(__GLIBC__) && defined(_LIBC)
|
||||
/* crypt.h from glibc-crypt-2.1 will define struct crypt_data for us */
|
||||
#include "crypt.h"
|
||||
extern char *__md5_crypt_r(const char *key, const char *salt,
|
||||
char *buffer, int buflen);
|
||||
/* crypt-entry.c needs to be patched to define __des_crypt_r rather than
|
||||
* __crypt_r, and not define crypt_r and crypt at all */
|
||||
extern char *__des_crypt_r(const char *key, const char *salt,
|
||||
struct crypt_data *data);
|
||||
extern struct crypt_data _ufc_foobar;
|
||||
#endif
|
||||
|
||||
static int _crypt_data_alloc(void **data, int *size, int need)
|
||||
{
|
||||
void *updated;
|
||||
|
||||
if (*data && *size >= need) return 0;
|
||||
|
||||
updated = realloc(*data, need);
|
||||
|
||||
if (!updated) {
|
||||
#ifndef __GLIBC__
|
||||
/* realloc(3) on glibc sets errno, so we don't need to bother */
|
||||
__set_errno(ENOMEM);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && defined(_LIBC)
|
||||
if (need >= sizeof(struct crypt_data))
|
||||
((struct crypt_data *)updated)->initialized = 0;
|
||||
#endif
|
||||
|
||||
*data = updated;
|
||||
*size = need;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *_crypt_retval_magic(char *retval, const char *setting,
|
||||
char *output, int size)
|
||||
{
|
||||
if (retval)
|
||||
return retval;
|
||||
|
||||
if (_crypt_output_magic(setting, output, size))
|
||||
return NULL; /* shouldn't happen */
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && defined(_LIBC)
|
||||
/*
|
||||
* Applications may re-use the same instance of struct crypt_data without
|
||||
* resetting the initialized field in order to let crypt_r() skip some of
|
||||
* its initialization code. Thus, it is important that our multiple hashing
|
||||
* algorithms either don't conflict with each other in their use of the
|
||||
* data area or reset the initialized field themselves whenever required.
|
||||
* Currently, the hashing algorithms simply have no conflicts: the first
|
||||
* field of struct crypt_data is the 128-byte large DES key schedule which
|
||||
* __des_crypt_r() calculates each time it is called while the two other
|
||||
* hashing algorithms use less than 128 bytes of the data area.
|
||||
*/
|
||||
|
||||
char *__crypt_rn(__const char *key, __const char *setting,
|
||||
void *data, int size)
|
||||
{
|
||||
if (setting[0] == '$' && setting[1] == '2')
|
||||
return _crypt_blowfish_rn(key, setting, (char *)data, size);
|
||||
if (setting[0] == '$' && setting[1] == '1')
|
||||
return __md5_crypt_r(key, setting, (char *)data, size);
|
||||
if (setting[0] == '$' || setting[0] == '_') {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
if (size >= sizeof(struct crypt_data))
|
||||
return __des_crypt_r(key, setting, (struct crypt_data *)data);
|
||||
__set_errno(ERANGE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *__crypt_ra(__const char *key, __const char *setting,
|
||||
void **data, int *size)
|
||||
{
|
||||
if (setting[0] == '$' && setting[1] == '2') {
|
||||
if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
|
||||
return NULL;
|
||||
return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
|
||||
}
|
||||
if (setting[0] == '$' && setting[1] == '1') {
|
||||
if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
|
||||
return NULL;
|
||||
return __md5_crypt_r(key, setting, (char *)*data, *size);
|
||||
}
|
||||
if (setting[0] == '$' || setting[0] == '_') {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
if (_crypt_data_alloc(data, size, sizeof(struct crypt_data)))
|
||||
return NULL;
|
||||
return __des_crypt_r(key, setting, (struct crypt_data *)*data);
|
||||
}
|
||||
|
||||
char *__crypt_r(__const char *key, __const char *setting,
|
||||
struct crypt_data *data)
|
||||
{
|
||||
return _crypt_retval_magic(
|
||||
__crypt_rn(key, setting, data, sizeof(*data)),
|
||||
setting, (char *)data, sizeof(*data));
|
||||
}
|
||||
|
||||
char *__crypt(__const char *key, __const char *setting)
|
||||
{
|
||||
return _crypt_retval_magic(
|
||||
__crypt_rn(key, setting, &_ufc_foobar, sizeof(_ufc_foobar)),
|
||||
setting, (char *)&_ufc_foobar, sizeof(_ufc_foobar));
|
||||
}
|
||||
#else
|
||||
char *crypt_rn(const char *key, const char *setting, void *data, int size)
|
||||
{
|
||||
return _crypt_blowfish_rn(key, setting, (char *)data, size);
|
||||
}
|
||||
|
||||
char *crypt_ra(const char *key, const char *setting,
|
||||
void **data, int *size)
|
||||
{
|
||||
if (_crypt_data_alloc(data, size, CRYPT_OUTPUT_SIZE))
|
||||
return NULL;
|
||||
return _crypt_blowfish_rn(key, setting, (char *)*data, *size);
|
||||
}
|
||||
|
||||
char *crypt_r(const char *key, const char *setting, void *data)
|
||||
{
|
||||
return _crypt_retval_magic(
|
||||
crypt_rn(key, setting, data, CRYPT_OUTPUT_SIZE),
|
||||
setting, (char *)data, CRYPT_OUTPUT_SIZE);
|
||||
}
|
||||
|
||||
char *crypt(const char *key, const char *setting)
|
||||
{
|
||||
static char output[CRYPT_OUTPUT_SIZE];
|
||||
|
||||
return _crypt_retval_magic(
|
||||
crypt_rn(key, setting, output, sizeof(output)),
|
||||
setting, output, sizeof(output));
|
||||
}
|
||||
|
||||
#define __crypt_gensalt_rn crypt_gensalt_rn
|
||||
#define __crypt_gensalt_ra crypt_gensalt_ra
|
||||
#define __crypt_gensalt crypt_gensalt
|
||||
#endif
|
||||
|
||||
char *__crypt_gensalt_rn(const char *prefix, unsigned long count,
|
||||
const char *input, int size, char *output, int output_size)
|
||||
{
|
||||
char *(*use)(const char *_prefix, unsigned long _count,
|
||||
const char *_input, int _size,
|
||||
char *_output, int _output_size);
|
||||
|
||||
/* This may be supported on some platforms in the future */
|
||||
if (!input) {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!strncmp(prefix, "$2a$", 4) || !strncmp(prefix, "$2b$", 4) ||
|
||||
!strncmp(prefix, "$2y$", 4))
|
||||
use = _crypt_gensalt_blowfish_rn;
|
||||
else
|
||||
if (!strncmp(prefix, "$1$", 3))
|
||||
use = _crypt_gensalt_md5_rn;
|
||||
else
|
||||
if (prefix[0] == '_')
|
||||
use = _crypt_gensalt_extended_rn;
|
||||
else
|
||||
if (!prefix[0] ||
|
||||
(prefix[0] && prefix[1] &&
|
||||
memchr(_crypt_itoa64, prefix[0], 64) &&
|
||||
memchr(_crypt_itoa64, prefix[1], 64)))
|
||||
use = _crypt_gensalt_traditional_rn;
|
||||
else {
|
||||
__set_errno(EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return use(prefix, count, input, size, output, output_size);
|
||||
}
|
||||
|
||||
char *__crypt_gensalt_ra(const char *prefix, unsigned long count,
|
||||
const char *input, int size)
|
||||
{
|
||||
char output[CRYPT_GENSALT_OUTPUT_SIZE];
|
||||
char *retval;
|
||||
|
||||
retval = __crypt_gensalt_rn(prefix, count,
|
||||
input, size, output, sizeof(output));
|
||||
|
||||
if (retval) {
|
||||
retval = strdup(retval);
|
||||
#ifndef __GLIBC__
|
||||
/* strdup(3) on glibc sets errno, so we don't need to bother */
|
||||
if (!retval)
|
||||
__set_errno(ENOMEM);
|
||||
#endif
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
char *__crypt_gensalt(const char *prefix, unsigned long count,
|
||||
const char *input, int size)
|
||||
{
|
||||
static char output[CRYPT_GENSALT_OUTPUT_SIZE];
|
||||
|
||||
return __crypt_gensalt_rn(prefix, count,
|
||||
input, size, output, sizeof(output));
|
||||
}
|
||||
|
||||
#if defined(__GLIBC__) && defined(_LIBC)
|
||||
weak_alias(__crypt_rn, crypt_rn)
|
||||
weak_alias(__crypt_ra, crypt_ra)
|
||||
weak_alias(__crypt_r, crypt_r)
|
||||
weak_alias(__crypt, crypt)
|
||||
weak_alias(__crypt_gensalt_rn, crypt_gensalt_rn)
|
||||
weak_alias(__crypt_gensalt_ra, crypt_gensalt_ra)
|
||||
weak_alias(__crypt_gensalt, crypt_gensalt)
|
||||
weak_alias(crypt, fcrypt)
|
||||
#endif
|
||||
|
||||
#ifdef TEST
|
||||
static const char *tests[][3] = {
|
||||
{"$2a$05$CCCCCCCCCCCCCCCCCCCCC.E5YPO9kmyuRGyh0XouQYb4YMJKvyOeW",
|
||||
"U*U"},
|
||||
{"$2a$05$CCCCCCCCCCCCCCCCCCCCC.VGOzA784oUp/Z0DY336zx7pLYAy0lwK",
|
||||
"U*U*"},
|
||||
{"$2a$05$XXXXXXXXXXXXXXXXXXXXXOAcXxm9kjPGEMsLznoKqmqw7tc8WCx4a",
|
||||
"U*U*U"},
|
||||
{"$2a$05$abcdefghijklmnopqrstuu5s2v8.iXieOjg/.AySBTTZIIVFJeBui",
|
||||
"0123456789abcdefghijklmnopqrstuvwxyz"
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
"chars after 72 are ignored"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
|
||||
"\xa3"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
|
||||
"\xff\xff\xa3"},
|
||||
{"$2y$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
|
||||
"\xff\xff\xa3"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nqd1wy.pTMdcvrRWxyiGL2eMz.2a85.",
|
||||
"\xff\xff\xa3"},
|
||||
{"$2b$05$/OK.fbVrR/bpIqNJ5ianF.CE5elHaaO4EbggVDjb8P19RukzXSM3e",
|
||||
"\xff\xff\xa3"},
|
||||
{"$2y$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
|
||||
"\xa3"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
|
||||
"\xa3"},
|
||||
{"$2b$05$/OK.fbVrR/bpIqNJ5ianF.Sa7shbm4.OzKpvFnX1pQLmQW96oUlCq",
|
||||
"\xa3"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
|
||||
"1\xa3" "345"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
|
||||
"\xff\xa3" "345"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
|
||||
"\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
|
||||
{"$2y$05$/OK.fbVrR/bpIqNJ5ianF.o./n25XVfn6oAPaUvHe.Csk4zRfsYPi",
|
||||
"\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.ZC1JEJ8Z4gPfpe1JOr/oyPXTWl9EFd.",
|
||||
"\xff\xa3" "34" "\xff\xff\xff\xa3" "345"},
|
||||
{"$2y$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
|
||||
"\xff\xa3" "345"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.nRht2l/HRhr6zmCp9vYUvvsqynflf9e",
|
||||
"\xff\xa3" "345"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
|
||||
"\xa3" "ab"},
|
||||
{"$2x$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
|
||||
"\xa3" "ab"},
|
||||
{"$2y$05$/OK.fbVrR/bpIqNJ5ianF.6IflQkJytoRVc1yuaNtHfiuq.FRlSIS",
|
||||
"\xa3" "ab"},
|
||||
{"$2x$05$6bNw2HLQYeqHYyBfLMsv/OiwqTymGIGzFsA4hOTWebfehXHNprcAS",
|
||||
"\xd1\x91"},
|
||||
{"$2x$05$6bNw2HLQYeqHYyBfLMsv/O9LIGgn8OMzuDoHfof8AQimSGfcSWxnS",
|
||||
"\xd0\xc1\xd2\xcf\xcc\xd8"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.swQOIzjOiJ9GHEPuhEkvqrUyvWhEMx6",
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
|
||||
"chars after 72 are ignored as usual"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.R9xrDjiycxMbQE2bp.vgqlYpW5wx2yy",
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"
|
||||
"\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55\xaa\x55"},
|
||||
{"$2a$05$/OK.fbVrR/bpIqNJ5ianF.9tQZzcJfm3uj2NvJ/n5xkhpqLrMpWCe",
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"
|
||||
"\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff\x55\xaa\xff"},
|
||||
{"$2a$05$CCCCCCCCCCCCCCCCCCCCC.7uG0VCzI2bS7j6ymqJi9CdcdxiRTWNy",
|
||||
""},
|
||||
{"*0", "", "$2a$03$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*0", "", "$2a$32$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*0", "", "$2c$05$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*0", "", "$2z$05$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*0", "", "$2`$05$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*0", "", "$2{$05$CCCCCCCCCCCCCCCCCCCCC."},
|
||||
{"*1", "", "*0"},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
#define which tests[0]
|
||||
|
||||
static volatile sig_atomic_t running;
|
||||
|
||||
static void handle_timer(int signum)
|
||||
{
|
||||
(void) signum;
|
||||
running = 0;
|
||||
}
|
||||
|
||||
static void *run(void *arg)
|
||||
{
|
||||
unsigned long count = 0;
|
||||
int i = 0;
|
||||
void *data = NULL;
|
||||
int size = 0x12345678;
|
||||
|
||||
do {
|
||||
const char *hash = tests[i][0];
|
||||
const char *key = tests[i][1];
|
||||
const char *setting = tests[i][2];
|
||||
|
||||
if (!tests[++i][0])
|
||||
i = 0;
|
||||
|
||||
if (setting && strlen(hash) < 30) /* not for benchmark */
|
||||
continue;
|
||||
|
||||
if (strcmp(crypt_ra(key, hash, &data, &size), hash)) {
|
||||
printf("%d: FAILED (crypt_ra/%d/%lu)\n",
|
||||
(int)((char *)arg - (char *)0), i, count);
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
count++;
|
||||
} while (running);
|
||||
|
||||
free(data);
|
||||
return count + (char *)0;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct itimerval it;
|
||||
struct tms buf;
|
||||
clock_t clk_tck, start_real, start_virtual, end_real, end_virtual;
|
||||
unsigned long count;
|
||||
void *data;
|
||||
int size;
|
||||
char *setting1, *setting2;
|
||||
int i;
|
||||
#ifdef TEST_THREADS
|
||||
pthread_t t[TEST_THREADS];
|
||||
void *t_retval;
|
||||
#endif
|
||||
|
||||
data = NULL;
|
||||
size = 0x12345678;
|
||||
|
||||
for (i = 0; tests[i][0]; i++) {
|
||||
const char *hash = tests[i][0];
|
||||
const char *key = tests[i][1];
|
||||
const char *setting = tests[i][2];
|
||||
const char *p;
|
||||
int ok = !setting || strlen(hash) >= 30;
|
||||
int o_size;
|
||||
char s_buf[30], o_buf[61];
|
||||
if (!setting) {
|
||||
memcpy(s_buf, hash, sizeof(s_buf) - 1);
|
||||
s_buf[sizeof(s_buf) - 1] = 0;
|
||||
setting = s_buf;
|
||||
}
|
||||
|
||||
__set_errno(0);
|
||||
p = crypt(key, setting);
|
||||
if ((!ok && !errno) || strcmp(p, hash)) {
|
||||
printf("FAILED (crypt/%d)\n", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ok && strcmp(crypt(key, hash), hash)) {
|
||||
printf("FAILED (crypt/%d)\n", i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (o_size = -1; o_size <= (int)sizeof(o_buf); o_size++) {
|
||||
int ok_n = ok && o_size == (int)sizeof(o_buf);
|
||||
const char *x = "abc";
|
||||
strcpy(o_buf, x);
|
||||
if (o_size >= 3) {
|
||||
x = "*0";
|
||||
if (setting[0] == '*' && setting[1] == '0')
|
||||
x = "*1";
|
||||
}
|
||||
__set_errno(0);
|
||||
p = crypt_rn(key, setting, o_buf, o_size);
|
||||
if ((ok_n && (!p || strcmp(p, hash))) ||
|
||||
(!ok_n && (!errno || p || strcmp(o_buf, x)))) {
|
||||
printf("FAILED (crypt_rn/%d)\n", i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
__set_errno(0);
|
||||
p = crypt_ra(key, setting, &data, &size);
|
||||
if ((ok && (!p || strcmp(p, hash))) ||
|
||||
(!ok && (!errno || p || strcmp((char *)data, hash)))) {
|
||||
printf("FAILED (crypt_ra/%d)\n", i);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
setting1 = crypt_gensalt(which[0], 12, data, size);
|
||||
if (!setting1 || strncmp(setting1, "$2a$12$", 7)) {
|
||||
puts("FAILED (crypt_gensalt)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
setting2 = crypt_gensalt_ra(setting1, 12, data, size);
|
||||
if (strcmp(setting1, setting2)) {
|
||||
puts("FAILED (crypt_gensalt_ra/1)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
(*(char *)data)++;
|
||||
setting1 = crypt_gensalt_ra(setting2, 12, data, size);
|
||||
if (!strcmp(setting1, setting2)) {
|
||||
puts("FAILED (crypt_gensalt_ra/2)\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
free(setting1);
|
||||
free(setting2);
|
||||
free(data);
|
||||
|
||||
#if defined(_SC_CLK_TCK) || !defined(CLK_TCK)
|
||||
clk_tck = sysconf(_SC_CLK_TCK);
|
||||
#else
|
||||
clk_tck = CLK_TCK;
|
||||
#endif
|
||||
|
||||
running = 1;
|
||||
signal(SIGALRM, handle_timer);
|
||||
|
||||
memset(&it, 0, sizeof(it));
|
||||
it.it_value.tv_sec = 5;
|
||||
setitimer(ITIMER_REAL, &it, NULL);
|
||||
|
||||
start_real = times(&buf);
|
||||
start_virtual = buf.tms_utime + buf.tms_stime;
|
||||
|
||||
count = (char *)run((char *)0) - (char *)0;
|
||||
|
||||
end_real = times(&buf);
|
||||
end_virtual = buf.tms_utime + buf.tms_stime;
|
||||
if (end_virtual == start_virtual) end_virtual++;
|
||||
|
||||
printf("%.1f c/s real, %.1f c/s virtual\n",
|
||||
(float)count * clk_tck / (end_real - start_real),
|
||||
(float)count * clk_tck / (end_virtual - start_virtual));
|
||||
|
||||
#ifdef TEST_THREADS
|
||||
running = 1;
|
||||
it.it_value.tv_sec = 60;
|
||||
setitimer(ITIMER_REAL, &it, NULL);
|
||||
start_real = times(&buf);
|
||||
|
||||
for (i = 0; i < TEST_THREADS; i++)
|
||||
if (pthread_create(&t[i], NULL, run, i + (char *)0)) {
|
||||
perror("pthread_create");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < TEST_THREADS; i++) {
|
||||
if (pthread_join(t[i], &t_retval)) {
|
||||
perror("pthread_join");
|
||||
continue;
|
||||
}
|
||||
if (!t_retval) continue;
|
||||
count = (char *)t_retval - (char *)0;
|
||||
end_real = times(&buf);
|
||||
printf("%d: %.1f c/s real\n", i,
|
||||
(float)count * clk_tck / (end_real - start_real));
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
203
deps/crypt_blowfish/x86.S
vendored
203
deps/crypt_blowfish/x86.S
vendored
@ -1,203 +0,0 @@
|
||||
/*
|
||||
* Written by Solar Designer <solar at openwall.com> in 1998-2010.
|
||||
* No copyright is claimed, and the software is hereby placed in the public
|
||||
* domain. In case this attempt to disclaim copyright and place the software
|
||||
* in the public domain is deemed null and void, then the software is
|
||||
* Copyright (c) 1998-2010 Solar Designer and it is hereby released to the
|
||||
* general public under the following terms:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted.
|
||||
*
|
||||
* There's ABSOLUTELY NO WARRANTY, express or implied.
|
||||
*
|
||||
* See crypt_blowfish.c for more information.
|
||||
*/
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#if defined(__OpenBSD__) && !defined(__ELF__)
|
||||
#define UNDERSCORES
|
||||
#define ALIGN_LOG
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN32__) || defined(__MINGW32__)
|
||||
#define UNDERSCORES
|
||||
#endif
|
||||
|
||||
#ifdef __DJGPP__
|
||||
#define UNDERSCORES
|
||||
#define ALIGN_LOG
|
||||
#endif
|
||||
|
||||
#ifdef UNDERSCORES
|
||||
#define _BF_body_r __BF_body_r
|
||||
#endif
|
||||
|
||||
#ifdef ALIGN_LOG
|
||||
#define DO_ALIGN(log) .align (log)
|
||||
#elif defined(DUMBAS)
|
||||
#define DO_ALIGN(log) .align 1 << log
|
||||
#else
|
||||
#define DO_ALIGN(log) .align (1 << (log))
|
||||
#endif
|
||||
|
||||
#define BF_FRAME 0x200
|
||||
#define ctx %esp
|
||||
|
||||
#define BF_ptr (ctx)
|
||||
|
||||
#define S(N, r) N+BF_FRAME(ctx,r,4)
|
||||
#ifdef DUMBAS
|
||||
#define P(N) 0x1000+N+N+N+N+BF_FRAME(ctx)
|
||||
#else
|
||||
#define P(N) 0x1000+4*N+BF_FRAME(ctx)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This version of the assembly code is optimized primarily for the original
|
||||
* Intel Pentium but is also careful to avoid partial register stalls on the
|
||||
* Pentium Pro family of processors (tested up to Pentium III Coppermine).
|
||||
*
|
||||
* It is possible to do 15% faster on the Pentium Pro family and probably on
|
||||
* many non-Intel x86 processors, but, unfortunately, that would make things
|
||||
* twice slower for the original Pentium.
|
||||
*
|
||||
* An additional 2% speedup may be achieved with non-reentrant code.
|
||||
*/
|
||||
|
||||
#define L %esi
|
||||
#define R %edi
|
||||
#define tmp1 %eax
|
||||
#define tmp1_lo %al
|
||||
#define tmp2 %ecx
|
||||
#define tmp2_hi %ch
|
||||
#define tmp3 %edx
|
||||
#define tmp3_lo %dl
|
||||
#define tmp4 %ebx
|
||||
#define tmp4_hi %bh
|
||||
#define tmp5 %ebp
|
||||
|
||||
.text
|
||||
|
||||
#define BF_ROUND(L, R, N) \
|
||||
xorl L,tmp2; \
|
||||
xorl tmp1,tmp1; \
|
||||
movl tmp2,L; \
|
||||
shrl $16,tmp2; \
|
||||
movl L,tmp4; \
|
||||
movb tmp2_hi,tmp1_lo; \
|
||||
andl $0xFF,tmp2; \
|
||||
movb tmp4_hi,tmp3_lo; \
|
||||
andl $0xFF,tmp4; \
|
||||
movl S(0,tmp1),tmp1; \
|
||||
movl S(0x400,tmp2),tmp5; \
|
||||
addl tmp5,tmp1; \
|
||||
movl S(0x800,tmp3),tmp5; \
|
||||
xorl tmp5,tmp1; \
|
||||
movl S(0xC00,tmp4),tmp5; \
|
||||
addl tmp1,tmp5; \
|
||||
movl 4+P(N),tmp2; \
|
||||
xorl tmp5,R
|
||||
|
||||
#define BF_ENCRYPT_START \
|
||||
BF_ROUND(L, R, 0); \
|
||||
BF_ROUND(R, L, 1); \
|
||||
BF_ROUND(L, R, 2); \
|
||||
BF_ROUND(R, L, 3); \
|
||||
BF_ROUND(L, R, 4); \
|
||||
BF_ROUND(R, L, 5); \
|
||||
BF_ROUND(L, R, 6); \
|
||||
BF_ROUND(R, L, 7); \
|
||||
BF_ROUND(L, R, 8); \
|
||||
BF_ROUND(R, L, 9); \
|
||||
BF_ROUND(L, R, 10); \
|
||||
BF_ROUND(R, L, 11); \
|
||||
BF_ROUND(L, R, 12); \
|
||||
BF_ROUND(R, L, 13); \
|
||||
BF_ROUND(L, R, 14); \
|
||||
BF_ROUND(R, L, 15); \
|
||||
movl BF_ptr,tmp5; \
|
||||
xorl L,tmp2; \
|
||||
movl P(17),L
|
||||
|
||||
#define BF_ENCRYPT_END \
|
||||
xorl R,L; \
|
||||
movl tmp2,R
|
||||
|
||||
DO_ALIGN(5)
|
||||
.globl _BF_body_r
|
||||
_BF_body_r:
|
||||
movl 4(%esp),%eax
|
||||
pushl %ebp
|
||||
pushl %ebx
|
||||
pushl %esi
|
||||
pushl %edi
|
||||
subl $BF_FRAME-8,%eax
|
||||
xorl L,L
|
||||
cmpl %esp,%eax
|
||||
ja BF_die
|
||||
xchgl %eax,%esp
|
||||
xorl R,R
|
||||
pushl %eax
|
||||
leal 0x1000+BF_FRAME-4(ctx),%eax
|
||||
movl 0x1000+BF_FRAME-4(ctx),tmp2
|
||||
pushl %eax
|
||||
xorl tmp3,tmp3
|
||||
BF_loop_P:
|
||||
BF_ENCRYPT_START
|
||||
addl $8,tmp5
|
||||
BF_ENCRYPT_END
|
||||
leal 0x1000+18*4+BF_FRAME(ctx),tmp1
|
||||
movl tmp5,BF_ptr
|
||||
cmpl tmp5,tmp1
|
||||
movl L,-8(tmp5)
|
||||
movl R,-4(tmp5)
|
||||
movl P(0),tmp2
|
||||
ja BF_loop_P
|
||||
leal BF_FRAME(ctx),tmp5
|
||||
xorl tmp3,tmp3
|
||||
movl tmp5,BF_ptr
|
||||
BF_loop_S:
|
||||
BF_ENCRYPT_START
|
||||
BF_ENCRYPT_END
|
||||
movl P(0),tmp2
|
||||
movl L,(tmp5)
|
||||
movl R,4(tmp5)
|
||||
BF_ENCRYPT_START
|
||||
BF_ENCRYPT_END
|
||||
movl P(0),tmp2
|
||||
movl L,8(tmp5)
|
||||
movl R,12(tmp5)
|
||||
BF_ENCRYPT_START
|
||||
BF_ENCRYPT_END
|
||||
movl P(0),tmp2
|
||||
movl L,16(tmp5)
|
||||
movl R,20(tmp5)
|
||||
BF_ENCRYPT_START
|
||||
addl $32,tmp5
|
||||
BF_ENCRYPT_END
|
||||
leal 0x1000+BF_FRAME(ctx),tmp1
|
||||
movl tmp5,BF_ptr
|
||||
cmpl tmp5,tmp1
|
||||
movl P(0),tmp2
|
||||
movl L,-8(tmp5)
|
||||
movl R,-4(tmp5)
|
||||
ja BF_loop_S
|
||||
movl 4(%esp),%esp
|
||||
popl %edi
|
||||
popl %esi
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
BF_die:
|
||||
/* Oops, need to re-compile with a larger BF_FRAME. */
|
||||
hlt
|
||||
jmp BF_die
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__ELF__) && defined(__linux__)
|
||||
.section .note.GNU-stack,"",@progbits
|
||||
#endif
|
1
deps/libbacktrace
vendored
Submodule
1
deps/libbacktrace
vendored
Submodule
Submodule deps/libbacktrace added at 9ae4f4ae44
5
deps/libbacktrace/.gitignore
vendored
5
deps/libbacktrace/.gitignore
vendored
@ -1,5 +0,0 @@
|
||||
*~
|
||||
*.o
|
||||
*.lo
|
||||
*.a
|
||||
*.la
|
9286
deps/libbacktrace/Isaac.Newton-Opticks.txt
vendored
9286
deps/libbacktrace/Isaac.Newton-Opticks.txt
vendored
File diff suppressed because it is too large
Load Diff
29
deps/libbacktrace/LICENSE
vendored
29
deps/libbacktrace/LICENSE
vendored
@ -1,29 +0,0 @@
|
||||
# Copyright (C) 2012-2016 Free Software Foundation, Inc.
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
|
||||
# (1) Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# (2) Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
|
||||
# (3) The name of the author may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
623
deps/libbacktrace/Makefile.am
vendored
623
deps/libbacktrace/Makefile.am
vendored
@ -1,623 +0,0 @@
|
||||
# Makefile.am -- Backtrace Makefile.
|
||||
# Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
|
||||
# (1) Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# (2) Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
|
||||
# (3) The name of the author may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ACLOCAL_AMFLAGS = -I config
|
||||
|
||||
AM_CPPFLAGS =
|
||||
|
||||
AM_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) $(PIC_FLAG)
|
||||
|
||||
include_HEADERS = backtrace.h backtrace-supported.h
|
||||
|
||||
lib_LTLIBRARIES = libbacktrace.la
|
||||
|
||||
libbacktrace_la_SOURCES = \
|
||||
backtrace.h \
|
||||
atomic.c \
|
||||
dwarf.c \
|
||||
fileline.c \
|
||||
internal.h \
|
||||
posix.c \
|
||||
print.c \
|
||||
sort.c \
|
||||
state.c
|
||||
|
||||
BACKTRACE_FILES = \
|
||||
backtrace.c \
|
||||
simple.c \
|
||||
nounwind.c
|
||||
|
||||
FORMAT_FILES = \
|
||||
elf.c \
|
||||
macho.c \
|
||||
pecoff.c \
|
||||
unknown.c \
|
||||
xcoff.c
|
||||
|
||||
VIEW_FILES = \
|
||||
read.c \
|
||||
mmapio.c
|
||||
|
||||
ALLOC_FILES = \
|
||||
alloc.c \
|
||||
mmap.c
|
||||
|
||||
EXTRA_libbacktrace_la_SOURCES = \
|
||||
$(BACKTRACE_FILES) \
|
||||
$(FORMAT_FILES) \
|
||||
$(VIEW_FILES) \
|
||||
$(ALLOC_FILES)
|
||||
|
||||
libbacktrace_la_LIBADD = \
|
||||
$(BACKTRACE_FILE) \
|
||||
$(FORMAT_FILE) \
|
||||
$(VIEW_FILE) \
|
||||
$(ALLOC_FILE)
|
||||
|
||||
libbacktrace_la_DEPENDENCIES = $(libbacktrace_la_LIBADD)
|
||||
|
||||
# Testsuite.
|
||||
|
||||
# Add a test to this variable if you want it to be built as a program,
|
||||
# with SOURCES, etc.
|
||||
check_PROGRAMS =
|
||||
|
||||
# Add a test to this variable if you want it to be run.
|
||||
TESTS =
|
||||
|
||||
# Add a test to this variable if you want it to be built as a Makefile
|
||||
# target and run.
|
||||
MAKETESTS =
|
||||
|
||||
# Add a test to this variable if you want it to be built as a program,
|
||||
# with SOURCES, etc., and run.
|
||||
BUILDTESTS =
|
||||
|
||||
# Add a file to this variable if you want it to be built for testing.
|
||||
check_DATA =
|
||||
|
||||
# Flags to use when compiling test programs.
|
||||
libbacktrace_TEST_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) -g
|
||||
|
||||
if USE_DSYMUTIL
|
||||
|
||||
%.dSYM: %
|
||||
$(DSYMUTIL) $<
|
||||
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if NATIVE
|
||||
check_LTLIBRARIES = libbacktrace_alloc.la
|
||||
|
||||
libbacktrace_alloc_la_SOURCES = $(libbacktrace_la_SOURCES)
|
||||
libbacktrace_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) read.lo alloc.lo
|
||||
|
||||
libbacktrace_alloc_la_DEPENDENCIES = $(libbacktrace_alloc_la_LIBADD)
|
||||
|
||||
check_LTLIBRARIES += libbacktrace_noformat.la
|
||||
|
||||
libbacktrace_noformat_la_SOURCES = $(libbacktrace_la_SOURCES)
|
||||
libbacktrace_noformat_la_LIBADD = $(BACKTRACE_FILE) $(VIEW_FILE) $(ALLOC_FILE)
|
||||
|
||||
libbacktrace_noformat_la_DEPENDENCIES = $(libbacktrace_noformat_la_LIBADD)
|
||||
|
||||
if HAVE_ELF
|
||||
if HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
TEST_BUILD_ID_DIR=$(abs_builddir)/usr/lib/debug/.build-id/
|
||||
|
||||
check_LTLIBRARIES += libbacktrace_elf_for_test.la
|
||||
|
||||
libbacktrace_elf_for_test_la_SOURCES = $(libbacktrace_la_SOURCES)
|
||||
libbacktrace_elf_for_test_la_LIBADD = $(BACKTRACE_FILE) elf_for_test.lo \
|
||||
$(VIEW_FILE) $(ALLOC_FILE)
|
||||
|
||||
elf_for_test.c: elf.c
|
||||
SEARCH='^#define SYSTEM_BUILD_ID_DIR.*$$'; \
|
||||
REPLACE="#define SYSTEM_BUILD_ID_DIR \"$(TEST_BUILD_ID_DIR)\""; \
|
||||
$(SED) "s%$$SEARCH%$$REPLACE%" \
|
||||
$< \
|
||||
> $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
endif HAVE_OBJCOPY_DEBUGLINK
|
||||
endif HAVE_ELF
|
||||
|
||||
elf_%.c: elf.c
|
||||
SEARCH='#error "Unknown BACKTRACE_ELF_SIZE"'; \
|
||||
REPLACE='#undef BACKTRACE_ELF_SIZE\
|
||||
#define BACKTRACE_ELF_SIZE'; \
|
||||
$(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \
|
||||
$< \
|
||||
> $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
xcoff_%.c: xcoff.c
|
||||
SEARCH='#error "Unknown BACKTRACE_XCOFF_SIZE"'; \
|
||||
REPLACE='#undef BACKTRACE_XCOFF_SIZE\
|
||||
#define BACKTRACE_XCOFF_SIZE'; \
|
||||
$(SED) "s/^$$SEARCH\$$/$$REPLACE $*/" \
|
||||
$< \
|
||||
> $@.tmp
|
||||
mv $@.tmp $@
|
||||
|
||||
test_elf_32_SOURCES = test_format.c testlib.c
|
||||
test_elf_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_elf_32_LDADD = libbacktrace_noformat.la elf_32.lo
|
||||
|
||||
BUILDTESTS += test_elf_32
|
||||
|
||||
test_elf_64_SOURCES = test_format.c testlib.c
|
||||
test_elf_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_elf_64_LDADD = libbacktrace_noformat.la elf_64.lo
|
||||
|
||||
BUILDTESTS += test_elf_64
|
||||
|
||||
test_macho_SOURCES = test_format.c testlib.c
|
||||
test_macho_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_macho_LDADD = libbacktrace_noformat.la macho.lo
|
||||
|
||||
BUILDTESTS += test_macho
|
||||
|
||||
test_xcoff_32_SOURCES = test_format.c testlib.c
|
||||
test_xcoff_32_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_xcoff_32_LDADD = libbacktrace_noformat.la xcoff_32.lo
|
||||
|
||||
BUILDTESTS += test_xcoff_32
|
||||
|
||||
test_xcoff_64_SOURCES = test_format.c testlib.c
|
||||
test_xcoff_64_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_xcoff_64_LDADD = libbacktrace_noformat.la xcoff_64.lo
|
||||
|
||||
BUILDTESTS += test_xcoff_64
|
||||
|
||||
test_pecoff_SOURCES = test_format.c testlib.c
|
||||
test_pecoff_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_pecoff_LDADD = libbacktrace_noformat.la pecoff.lo
|
||||
|
||||
BUILDTESTS += test_pecoff
|
||||
|
||||
test_unknown_SOURCES = test_format.c testlib.c
|
||||
test_unknown_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
test_unknown_LDADD = libbacktrace_noformat.la unknown.lo
|
||||
|
||||
BUILDTESTS += test_unknown
|
||||
|
||||
unittest_SOURCES = unittest.c testlib.c
|
||||
unittest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
unittest_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += unittest
|
||||
|
||||
unittest_alloc_SOURCES = $(unittest_SOURCES)
|
||||
unittest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
unittest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
BUILDTESTS += unittest_alloc
|
||||
|
||||
check_LTLIBRARIES += libbacktrace_instrumented_alloc.la
|
||||
|
||||
libbacktrace_instrumented_alloc_la_SOURCES = $(libbacktrace_la_SOURCES)
|
||||
libbacktrace_instrumented_alloc_la_LIBADD = $(BACKTRACE_FILE) $(FORMAT_FILE) \
|
||||
read.lo instrumented_alloc.lo
|
||||
|
||||
libbacktrace_instrumented_alloc_la_DEPENDENCIES = \
|
||||
$(libbacktrace_instrumented_alloc_la_LIBADD)
|
||||
|
||||
instrumented_alloc.lo: alloc.c
|
||||
|
||||
allocfail_SOURCES = allocfail.c testlib.c
|
||||
allocfail_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
allocfail_LDADD = libbacktrace_instrumented_alloc.la
|
||||
|
||||
check_PROGRAMS += allocfail
|
||||
|
||||
allocfail.sh: allocfail
|
||||
|
||||
TESTS += allocfail.sh
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += allocfail.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if HAVE_ELF
|
||||
if HAVE_BUILDID
|
||||
if HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
b2test_SOURCES = $(btest_SOURCES)
|
||||
b2test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
b2test_LDFLAGS = -Wl,--build-id
|
||||
b2test_LDADD = libbacktrace_elf_for_test.la
|
||||
|
||||
check_PROGRAMS += b2test
|
||||
MAKETESTS += b2test_buildid
|
||||
|
||||
if HAVE_DWZ
|
||||
|
||||
b3test_SOURCES = $(btest_SOURCES)
|
||||
b3test_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
b3test_LDFLAGS = -Wl,--build-id
|
||||
b3test_LDADD = libbacktrace_elf_for_test.la
|
||||
|
||||
check_PROGRAMS += b3test
|
||||
MAKETESTS += b3test_dwz_buildid
|
||||
|
||||
endif HAVE_DWZ
|
||||
|
||||
endif HAVE_OBJCOPY_DEBUGLINK
|
||||
endif HAVE_BUILDID
|
||||
endif HAVE_ELF
|
||||
|
||||
btest_SOURCES = btest.c testlib.c
|
||||
btest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O
|
||||
btest_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += btest
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += btest.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if HAVE_ELF
|
||||
|
||||
btest_lto_SOURCES = btest.c testlib.c
|
||||
btest_lto_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O -flto
|
||||
btest_lto_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += btest_lto
|
||||
|
||||
endif HAVE_ELF
|
||||
|
||||
btest_alloc_SOURCES = $(btest_SOURCES)
|
||||
btest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
btest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
BUILDTESTS += btest_alloc
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += btest_alloc.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if HAVE_DWZ
|
||||
|
||||
%_dwz: %
|
||||
rm -f $@ $@_common.debug
|
||||
cp $< $@_1
|
||||
cp $< $@_2
|
||||
if $(DWZ) -m $@_common.debug $@_1 $@_2; then \
|
||||
rm -f $@_2; \
|
||||
mv $@_1 $@; \
|
||||
else \
|
||||
echo "Ignoring dwz errors, assuming that test passes"; \
|
||||
cp $< $@; \
|
||||
fi
|
||||
|
||||
MAKETESTS += btest_dwz
|
||||
|
||||
if HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
MAKETESTS += btest_dwz_gnudebuglink
|
||||
|
||||
endif HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
endif HAVE_DWZ
|
||||
|
||||
stest_SOURCES = stest.c
|
||||
stest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
stest_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += stest
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += stest.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
stest_alloc_SOURCES = $(stest_SOURCES)
|
||||
stest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
stest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
BUILDTESTS += stest_alloc
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += stest_alloc.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if HAVE_ELF
|
||||
|
||||
ztest_SOURCES = ztest.c testlib.c
|
||||
ztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\"
|
||||
ztest_LDADD = libbacktrace.la
|
||||
ztest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
if HAVE_ZLIB
|
||||
ztest_LDADD += -lz
|
||||
ztest_alloc_LDADD += -lz
|
||||
endif
|
||||
ztest_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
ztest_alloc_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
|
||||
BUILDTESTS += ztest
|
||||
|
||||
ztest_alloc_SOURCES = $(ztest_SOURCES)
|
||||
ztest_alloc_CFLAGS = $(ztest_CFLAGS)
|
||||
|
||||
BUILDTESTS += ztest_alloc
|
||||
|
||||
zstdtest_SOURCES = zstdtest.c testlib.c
|
||||
zstdtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\"
|
||||
zstdtest_LDADD = libbacktrace.la
|
||||
zstdtest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
if HAVE_ZSTD
|
||||
zstdtest_LDADD += -lzstd
|
||||
zstdtest_alloc_LDADD += -lzstd
|
||||
endif
|
||||
zstdtest_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
zstdtest_alloc_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
|
||||
BUILDTESTS += zstdtest
|
||||
|
||||
zstdtest_alloc_SOURCES = $(zstdtest_SOURCES)
|
||||
zstdtest_alloc_CFLAGS = $(zstdtest_CFLAGS)
|
||||
|
||||
BUILDTESTS += zstdtest_alloc
|
||||
|
||||
endif HAVE_ELF
|
||||
|
||||
edtest_SOURCES = edtest.c edtest2_build.c testlib.c
|
||||
edtest_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
edtest_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += edtest
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += edtest.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
edtest_alloc_SOURCES = $(edtest_SOURCES)
|
||||
edtest_alloc_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
edtest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += edtest_alloc.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
BUILDTESTS += edtest_alloc
|
||||
|
||||
edtest2_build.c: gen_edtest2_build; @true
|
||||
gen_edtest2_build: $(srcdir)/edtest2.c
|
||||
cat $(srcdir)/edtest2.c > tmp-edtest2_build.c
|
||||
$(SHELL) $(srcdir)/move-if-change tmp-edtest2_build.c edtest2_build.c
|
||||
echo timestamp > $@
|
||||
|
||||
if HAVE_PTHREAD
|
||||
|
||||
BUILDTESTS += ttest
|
||||
|
||||
ttest_SOURCES = ttest.c testlib.c
|
||||
ttest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -pthread
|
||||
ttest_LDADD = libbacktrace.la
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += ttest.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
BUILDTESTS += ttest_alloc
|
||||
|
||||
ttest_alloc_SOURCES = $(ttest_SOURCES)
|
||||
ttest_alloc_CFLAGS = $(ttest_CFLAGS)
|
||||
ttest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += ttest_alloc.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
endif HAVE_PTHREAD
|
||||
|
||||
if HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
MAKETESTS += btest_gnudebuglink
|
||||
|
||||
%_gnudebuglink: %
|
||||
$(OBJCOPY) --only-keep-debug $< $@.debug
|
||||
$(OBJCOPY) --strip-debug --add-gnu-debuglink=$@.debug $< $@
|
||||
|
||||
endif HAVE_OBJCOPY_DEBUGLINK
|
||||
|
||||
%_buildid: %
|
||||
./install-debuginfo-for-buildid.sh \
|
||||
"$(TEST_BUILD_ID_DIR)" \
|
||||
$<
|
||||
$(OBJCOPY) --strip-debug $< $@
|
||||
|
||||
if HAVE_COMPRESSED_DEBUG
|
||||
|
||||
ctestg_SOURCES = btest.c testlib.c
|
||||
ctestg_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
ctestg_LDFLAGS = -Wl,--compress-debug-sections=zlib-gnu
|
||||
ctestg_LDADD = libbacktrace.la
|
||||
|
||||
ctesta_SOURCES = btest.c testlib.c
|
||||
ctesta_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
ctesta_LDFLAGS = -Wl,--compress-debug-sections=zlib-gabi
|
||||
ctesta_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += ctestg ctesta
|
||||
|
||||
if HAVE_COMPRESSED_DEBUG_ZSTD
|
||||
|
||||
ctestzstd_SOURCES = btest.c testlib.c
|
||||
ctestzstd_CFLAGS = $(libbacktrace_TEST_CFLAGS)
|
||||
ctestzstd_LDFLAGS = -Wl,--compress-debug-sections=zstd
|
||||
ctestzstd_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += ctestzstd
|
||||
|
||||
endif
|
||||
|
||||
ctestg_alloc_SOURCES = $(ctestg_SOURCES)
|
||||
ctestg_alloc_CFLAGS = $(ctestg_CFLAGS)
|
||||
ctestg_alloc_LDFLAGS = $(ctestg_LDFLAGS)
|
||||
ctestg_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
ctesta_alloc_SOURCES = $(ctesta_SOURCES)
|
||||
ctesta_alloc_CFLAGS = $(ctesta_CFLAGS)
|
||||
ctesta_alloc_LDFLAGS = $(ctesta_LDFLAGS)
|
||||
ctesta_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
BUILDTESTS += ctestg_alloc ctesta_alloc
|
||||
|
||||
endif
|
||||
|
||||
if HAVE_DWARF5
|
||||
|
||||
dwarf5_SOURCES = btest.c testlib.c
|
||||
dwarf5_CFLAGS = $(libbacktrace_TEST_CFLAGS) -gdwarf-5
|
||||
dwarf5_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += dwarf5
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += dwarf5.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
dwarf5_alloc_SOURCES = $(dwarf5_SOURCES)
|
||||
dwarf5_alloc_CFLAGS = $(dwarf5_CFLAGS)
|
||||
dwarf5_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
BUILDTESTS += dwarf5_alloc
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += dwarf5_alloc.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
endif
|
||||
|
||||
mtest_SOURCES = mtest.c testlib.c
|
||||
mtest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -O
|
||||
mtest_LDADD = libbacktrace.la
|
||||
|
||||
BUILDTESTS += mtest
|
||||
|
||||
if USE_DSYMUTIL
|
||||
check_DATA += mtest.dSYM
|
||||
endif USE_DSYMUTIL
|
||||
|
||||
if HAVE_MINIDEBUG
|
||||
|
||||
MAKETESTS += mtest_minidebug
|
||||
|
||||
%_minidebug: %
|
||||
$(NM) -D $< -P --defined-only | $(AWK) '{ print $$1 }' | sort > $<.dsyms
|
||||
$(NM) $< -P --defined-only | $(AWK) '{ if ($$2 == "T" || $$2 == "t" || $$2 == "D") print $$1 }' | sort > $<.fsyms
|
||||
$(COMM) -13 $<.dsyms $<.fsyms > $<.keepsyms
|
||||
$(OBJCOPY) --only-keep-debug $< $<.dbg
|
||||
$(OBJCOPY) -S --remove-section .gdb_index --remove-section .comment --keep-symbols=$<.keepsyms $<.dbg $<.mdbg
|
||||
$(OBJCOPY) --strip-all --remove-section ..comment $< $<.strip
|
||||
rm -f $<.mdbg.xz
|
||||
$(XZ) $<.mdbg
|
||||
$(OBJCOPY) --add-section .gnu_debugdata=$<.mdbg.xz $<.strip
|
||||
mv $<.strip $@
|
||||
|
||||
endif HAVE_MINIDEBUG
|
||||
|
||||
endif NATIVE
|
||||
|
||||
if HAVE_ELF
|
||||
|
||||
xztest_SOURCES = xztest.c testlib.c
|
||||
xztest_CFLAGS = $(libbacktrace_TEST_CFLAGS) -DSRCDIR=\"$(srcdir)\"
|
||||
xztest_LDADD = libbacktrace.la
|
||||
|
||||
xztest_alloc_SOURCES = $(xztest_SOURCES)
|
||||
xztest_alloc_CFLAGS = $(xztest_CFLAGS)
|
||||
xztest_alloc_LDADD = libbacktrace_alloc.la
|
||||
|
||||
if HAVE_LIBLZMA
|
||||
xztest_LDADD += -llzma
|
||||
xztest_alloc_LDADD += -llzma
|
||||
endif
|
||||
|
||||
xztest_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
xztest_alloc_LDADD += $(CLOCK_GETTIME_LINK)
|
||||
|
||||
BUILDTESTS += xztest xztest_alloc
|
||||
|
||||
endif HAVE_ELF
|
||||
|
||||
check_PROGRAMS += $(BUILDTESTS)
|
||||
|
||||
TESTS += $(MAKETESTS) $(BUILDTESTS)
|
||||
|
||||
CLEANFILES = \
|
||||
$(MAKETESTS) $(BUILDTESTS) *.debug elf_for_test.c edtest2_build.c \
|
||||
gen_edtest2_build \
|
||||
*.dsyms *.fsyms *.keepsyms *.dbg *.mdbg *.mdbg.xz *.strip
|
||||
|
||||
clean-local:
|
||||
-rm -rf usr
|
||||
|
||||
# We can't use automake's automatic dependency tracking, because it
|
||||
# breaks when using bootstrap-lean. Automatic dependency tracking
|
||||
# with GCC bootstrap will cause some of the objects to depend on
|
||||
# header files in prev-gcc/include, e.g., stddef.h and stdarg.h. When
|
||||
# using bootstrap-lean, prev-gcc is removed after each stage. When
|
||||
# running "make install", those header files will be gone, causing the
|
||||
# library to be rebuilt at install time. That may not succeed.
|
||||
|
||||
# These manual dependencies do not include dependencies on unwind.h,
|
||||
# even though that is part of GCC, because where to find it depends on
|
||||
# whether we are being built as a host library or a target library.
|
||||
|
||||
alloc.lo: config.h backtrace.h internal.h
|
||||
backtrace.lo: config.h backtrace.h internal.h
|
||||
btest.lo: filenames.h backtrace.h backtrace-supported.h
|
||||
dwarf.lo: config.h filenames.h backtrace.h internal.h
|
||||
elf.lo: config.h backtrace.h internal.h
|
||||
fileline.lo: config.h backtrace.h internal.h
|
||||
macho.lo: config.h backtrace.h internal.h
|
||||
mmap.lo: config.h backtrace.h internal.h
|
||||
mmapio.lo: config.h backtrace.h internal.h
|
||||
mtest.lo: backtrace.h backtrace-supported.h
|
||||
nounwind.lo: config.h internal.h
|
||||
pecoff.lo: config.h backtrace.h internal.h
|
||||
posix.lo: config.h backtrace.h internal.h
|
||||
print.lo: config.h backtrace.h internal.h
|
||||
read.lo: config.h backtrace.h internal.h
|
||||
simple.lo: config.h backtrace.h internal.h
|
||||
sort.lo: config.h backtrace.h internal.h
|
||||
stest.lo: config.h backtrace.h internal.h
|
||||
state.lo: config.h backtrace.h backtrace-supported.h internal.h
|
||||
unknown.lo: config.h backtrace.h internal.h
|
||||
xcoff.lo: config.h backtrace.h internal.h
|
||||
xztest.lo: config.h backtrace.h backtrace-supported.h internal.h testlib.h
|
||||
ztest.lo: config.h backtrace.h backtrace-supported.h internal.h testlib.h
|
||||
|
2666
deps/libbacktrace/Makefile.in
vendored
2666
deps/libbacktrace/Makefile.in
vendored
File diff suppressed because it is too large
Load Diff
36
deps/libbacktrace/README.md
vendored
36
deps/libbacktrace/README.md
vendored
@ -1,36 +0,0 @@
|
||||
# libbacktrace
|
||||
A C library that may be linked into a C/C++ program to produce symbolic backtraces
|
||||
|
||||
Initially written by Ian Lance Taylor <iant@golang.org>.
|
||||
|
||||
This is version 1.0.
|
||||
It is likely that this will always be version 1.0.
|
||||
|
||||
The libbacktrace library may be linked into a program or library and
|
||||
used to produce symbolic backtraces.
|
||||
Sample uses would be to print a detailed backtrace when an error
|
||||
occurs or to gather detailed profiling information.
|
||||
In general the functions provided by this library are async-signal-safe,
|
||||
meaning that they may be safely called from a signal handler.
|
||||
|
||||
The libbacktrace library is provided under a BSD license.
|
||||
See the source files for the exact license text.
|
||||
|
||||
The public functions are declared and documented in the header file
|
||||
backtrace.h, which should be #include'd by a user of the library.
|
||||
|
||||
Building libbacktrace will generate a file backtrace-supported.h,
|
||||
which a user of the library may use to determine whether backtraces
|
||||
will work.
|
||||
See the source file backtrace-supported.h.in for the macros that it
|
||||
defines.
|
||||
|
||||
As of October 2020, libbacktrace supports ELF, PE/COFF, Mach-O, and
|
||||
XCOFF executables with DWARF debugging information.
|
||||
In other words, it supports GNU/Linux, *BSD, macOS, Windows, and AIX.
|
||||
The library is written to make it straightforward to add support for
|
||||
other object file and debugging formats.
|
||||
|
||||
The library relies on the C++ unwind API defined at
|
||||
https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html
|
||||
This API is provided by GCC and clang.
|
864
deps/libbacktrace/aclocal.m4
vendored
864
deps/libbacktrace/aclocal.m4
vendored
@ -1,864 +0,0 @@
|
||||
# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
|
||||
[m4_warning([this file was generated for autoconf 2.69.
|
||||
You have another version of autoconf. It may work, but is not guaranteed to.
|
||||
If you have problems, you may need to regenerate the build system entirely.
|
||||
To do so, use the procedure documented by the package, typically 'autoreconf'.])])
|
||||
|
||||
# Copyright (C) 2002-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_AUTOMAKE_VERSION(VERSION)
|
||||
# ----------------------------
|
||||
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||
# generated from the m4 files accompanying Automake X.Y.
|
||||
# (This private macro should not be called outside this file.)
|
||||
AC_DEFUN([AM_AUTOMAKE_VERSION],
|
||||
[am__api_version='1.15'
|
||||
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
|
||||
dnl require some minimum version. Point them to the right macro.
|
||||
m4_if([$1], [1.15.1], [],
|
||||
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
|
||||
])
|
||||
|
||||
# _AM_AUTOCONF_VERSION(VERSION)
|
||||
# -----------------------------
|
||||
# aclocal traces this macro to find the Autoconf version.
|
||||
# This is a private macro too. Using m4_define simplifies
|
||||
# the logic in aclocal, which can simply ignore this definition.
|
||||
m4_define([_AM_AUTOCONF_VERSION], [])
|
||||
|
||||
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||
# -------------------------------
|
||||
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
|
||||
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.15.1])dnl
|
||||
m4_ifndef([AC_AUTOCONF_VERSION],
|
||||
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
|
||||
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
|
||||
|
||||
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||
# $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to
|
||||
# '$srcdir', '$srcdir/..', or '$srcdir/../..'.
|
||||
#
|
||||
# Of course, Automake must honor this variable whenever it calls a
|
||||
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||
# depending on how configure is run. This is pretty annoying, since
|
||||
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||
# source directory, any form will work fine, but in subdirectories a
|
||||
# relative path needs to be adjusted first.
|
||||
#
|
||||
# $ac_aux_dir/missing
|
||||
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||
# $top_srcdir/$ac_aux_dir/missing
|
||||
# fails if $ac_aux_dir is absolute,
|
||||
# fails when called from a subdirectory in a VPATH build with
|
||||
# a relative $ac_aux_dir
|
||||
#
|
||||
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||
# harmless because $srcdir is '.', but things will broke when you
|
||||
# start a VPATH build or use an absolute $srcdir.
|
||||
#
|
||||
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||
# and then we would define $MISSING as
|
||||
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||
# This will work as long as MISSING is not called from configure, because
|
||||
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||
# However there are other variables, like CC, which are often used in
|
||||
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||
#
|
||||
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||
# configured tree to be moved without reconfiguration.
|
||||
|
||||
AC_DEFUN([AM_AUX_DIR_EXPAND],
|
||||
[AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
|
||||
# Expand $ac_aux_dir to an absolute path.
|
||||
am_aux_dir=`cd "$ac_aux_dir" && pwd`
|
||||
])
|
||||
|
||||
# AM_CONDITIONAL -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||
# -------------------------------------
|
||||
# Define a conditional.
|
||||
AC_DEFUN([AM_CONDITIONAL],
|
||||
[AC_PREREQ([2.52])dnl
|
||||
m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||
AC_SUBST([$1_TRUE])dnl
|
||||
AC_SUBST([$1_FALSE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_TRUE])dnl
|
||||
_AM_SUBST_NOTMAKE([$1_FALSE])dnl
|
||||
m4_define([_AM_COND_VALUE_$1], [$2])dnl
|
||||
if $2; then
|
||||
$1_TRUE=
|
||||
$1_FALSE='#'
|
||||
else
|
||||
$1_TRUE='#'
|
||||
$1_FALSE=
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||
AC_MSG_ERROR([[conditional "$1" was never defined.
|
||||
Usually this means the macro was only invoked conditionally.]])
|
||||
fi])])
|
||||
|
||||
# Do all the work for Automake. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This macro actually does too much. Some checks are only needed if
|
||||
# your package does certain things. But this isn't really a big deal.
|
||||
|
||||
dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O.
|
||||
m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])
|
||||
[_AM_PROG_CC_C_O
|
||||
])
|
||||
|
||||
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||
# -----------------------------------------------
|
||||
# The call with PACKAGE and VERSION arguments is the old style
|
||||
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||
# and VERSION should now be passed to AC_INIT and removed from
|
||||
# the call to AM_INIT_AUTOMAKE.
|
||||
# We support both call styles for the transition. After
|
||||
# the next Automake release, Autoconf can make the AC_INIT
|
||||
# arguments mandatory, and then we can depend on a new Autoconf
|
||||
# release and drop the old call support.
|
||||
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||
[AC_PREREQ([2.65])dnl
|
||||
dnl Autoconf wants to disallow AM_ names. We explicitly allow
|
||||
dnl the ones we care about.
|
||||
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||
if test "`cd $srcdir && pwd`" != "`pwd`"; then
|
||||
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
|
||||
# is not polluted with repeated "-I."
|
||||
AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
|
||||
# test to see if srcdir already configured
|
||||
if test -f $srcdir/config.status; then
|
||||
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||
fi
|
||||
fi
|
||||
|
||||
# test whether we have cygpath
|
||||
if test -z "$CYGPATH_W"; then
|
||||
if (cygpath --version) >/dev/null 2>/dev/null; then
|
||||
CYGPATH_W='cygpath -w'
|
||||
else
|
||||
CYGPATH_W=echo
|
||||
fi
|
||||
fi
|
||||
AC_SUBST([CYGPATH_W])
|
||||
|
||||
# Define the identity of the package.
|
||||
dnl Distinguish between old-style and new-style calls.
|
||||
m4_ifval([$2],
|
||||
[AC_DIAGNOSE([obsolete],
|
||||
[$0: two- and three-arguments forms are deprecated.])
|
||||
m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||
AC_SUBST([PACKAGE], [$1])dnl
|
||||
AC_SUBST([VERSION], [$2])],
|
||||
[_AM_SET_OPTIONS([$1])dnl
|
||||
dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
|
||||
m4_if(
|
||||
m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
|
||||
[ok:ok],,
|
||||
[m4_fatal([AC_INIT should be called with package and version arguments])])dnl
|
||||
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
|
||||
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
|
||||
|
||||
_AM_IF_OPTION([no-define],,
|
||||
[AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package])
|
||||
AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl
|
||||
|
||||
# Some tools Automake needs.
|
||||
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||
AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOCONF], [autoconf])
|
||||
AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}])
|
||||
AM_MISSING_PROG([AUTOHEADER], [autoheader])
|
||||
AM_MISSING_PROG([MAKEINFO], [makeinfo])
|
||||
AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
|
||||
AC_REQUIRE([AC_PROG_MKDIR_P])dnl
|
||||
# For better backward compatibility. To be removed once Automake 1.9.x
|
||||
# dies out for good. For more background, see:
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00001.html>
|
||||
# <http://lists.gnu.org/archive/html/automake/2012-07/msg00014.html>
|
||||
AC_SUBST([mkdir_p], ['$(MKDIR_P)'])
|
||||
# We need awk for the "check" target (and possibly the TAP driver). The
|
||||
# system "awk" is bad on some platforms.
|
||||
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
|
||||
_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
|
||||
[_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
|
||||
[_AM_PROG_TAR([v7])])])
|
||||
_AM_IF_OPTION([no-dependencies],,
|
||||
[AC_PROVIDE_IFELSE([AC_PROG_CC],
|
||||
[_AM_DEPENDENCIES([CC])],
|
||||
[m4_define([AC_PROG_CC],
|
||||
m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_CXX],
|
||||
[_AM_DEPENDENCIES([CXX])],
|
||||
[m4_define([AC_PROG_CXX],
|
||||
m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJC],
|
||||
[_AM_DEPENDENCIES([OBJC])],
|
||||
[m4_define([AC_PROG_OBJC],
|
||||
m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl
|
||||
AC_PROVIDE_IFELSE([AC_PROG_OBJCXX],
|
||||
[_AM_DEPENDENCIES([OBJCXX])],
|
||||
[m4_define([AC_PROG_OBJCXX],
|
||||
m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
|
||||
])
|
||||
AC_REQUIRE([AM_SILENT_RULES])dnl
|
||||
dnl The testsuite driver may need to know about EXEEXT, so add the
|
||||
dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This
|
||||
dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below.
|
||||
AC_CONFIG_COMMANDS_PRE(dnl
|
||||
[m4_provide_if([_AM_COMPILER_EXEEXT],
|
||||
[AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
|
||||
|
||||
# POSIX will say in a future version that running "rm -f" with no argument
|
||||
# is OK; and we want to be able to make that assumption in our Makefile
|
||||
# recipes. So use an aggressive probe to check that the usage we want is
|
||||
# actually supported "in the wild" to an acceptable degree.
|
||||
# See automake bug#10828.
|
||||
# To make any issue more visible, cause the running configure to be aborted
|
||||
# by default if the 'rm' program in use doesn't match our expectations; the
|
||||
# user can still override this though.
|
||||
if rm -f && rm -fr && rm -rf; then : OK; else
|
||||
cat >&2 <<'END'
|
||||
Oops!
|
||||
|
||||
Your 'rm' program seems unable to run without file operands specified
|
||||
on the command line, even when the '-f' option is present. This is contrary
|
||||
to the behaviour of most rm programs out there, and not conforming with
|
||||
the upcoming POSIX standard: <http://austingroupbugs.net/view.php?id=542>
|
||||
|
||||
Please tell bug-automake@gnu.org about your system, including the value
|
||||
of your $PATH and any error possibly output before this message. This
|
||||
can help us improve future automake versions.
|
||||
|
||||
END
|
||||
if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then
|
||||
echo 'Configuration will proceed anyway, since you have set the' >&2
|
||||
echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2
|
||||
echo >&2
|
||||
else
|
||||
cat >&2 <<'END'
|
||||
Aborting the configuration process, to ensure you take notice of the issue.
|
||||
|
||||
You can download and install GNU coreutils to get an 'rm' implementation
|
||||
that behaves properly: <http://www.gnu.org/software/coreutils/>.
|
||||
|
||||
If you want to complete the configuration process using your problematic
|
||||
'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM
|
||||
to "yes", and re-run configure.
|
||||
|
||||
END
|
||||
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
|
||||
fi
|
||||
fi
|
||||
dnl The trailing newline in this macro's definition is deliberate, for
|
||||
dnl backward compatibility and to allow trailing 'dnl'-style comments
|
||||
dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841.
|
||||
])
|
||||
|
||||
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
|
||||
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
|
||||
dnl mangled by Autoconf and run in a shell conditional statement.
|
||||
m4_define([_AC_COMPILER_EXEEXT],
|
||||
m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp files are numbered to have different names.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[# Compute $1's index in $config_headers.
|
||||
_am_arg=$1
|
||||
_am_stamp_count=1
|
||||
for _am_header in $config_headers :; do
|
||||
case $_am_header in
|
||||
$_am_arg | $_am_arg:* )
|
||||
break ;;
|
||||
* )
|
||||
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
|
||||
esac
|
||||
done
|
||||
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
|
||||
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_SH
|
||||
# ------------------
|
||||
# Define $install_sh.
|
||||
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
if test x"${install_sh+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
|
||||
*)
|
||||
install_sh="\${SHELL} $am_aux_dir/install-sh"
|
||||
esac
|
||||
fi
|
||||
AC_SUBST([install_sh])])
|
||||
|
||||
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
|
||||
# From Jim Meyering
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_MAINTAINER_MODE([DEFAULT-MODE])
|
||||
# ----------------------------------
|
||||
# Control maintainer-specific portions of Makefiles.
|
||||
# Default is to disable them, unless 'enable' is passed literally.
|
||||
# For symmetry, 'disable' may be passed as well. Anyway, the user
|
||||
# can override the default with the --enable/--disable switch.
|
||||
AC_DEFUN([AM_MAINTAINER_MODE],
|
||||
[m4_case(m4_default([$1], [disable]),
|
||||
[enable], [m4_define([am_maintainer_other], [disable])],
|
||||
[disable], [m4_define([am_maintainer_other], [enable])],
|
||||
[m4_define([am_maintainer_other], [enable])
|
||||
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
|
||||
AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
|
||||
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
|
||||
AC_ARG_ENABLE([maintainer-mode],
|
||||
[AS_HELP_STRING([--]am_maintainer_other[-maintainer-mode],
|
||||
am_maintainer_other[ make rules and dependencies not useful
|
||||
(and sometimes confusing) to the casual installer])],
|
||||
[USE_MAINTAINER_MODE=$enableval],
|
||||
[USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
|
||||
AC_MSG_RESULT([$USE_MAINTAINER_MODE])
|
||||
AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
|
||||
MAINT=$MAINTAINER_MODE_TRUE
|
||||
AC_SUBST([MAINT])dnl
|
||||
]
|
||||
)
|
||||
|
||||
# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1997-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||
# ------------------------------
|
||||
AC_DEFUN([AM_MISSING_PROG],
|
||||
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||
$1=${$1-"${am_missing_run}$2"}
|
||||
AC_SUBST($1)])
|
||||
|
||||
# AM_MISSING_HAS_RUN
|
||||
# ------------------
|
||||
# Define MISSING if not defined so far and test if it is modern enough.
|
||||
# If it is, set am_missing_run to use it, otherwise, to nothing.
|
||||
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([missing])dnl
|
||||
if test x"${MISSING+set}" != xset; then
|
||||
case $am_aux_dir in
|
||||
*\ * | *\ *)
|
||||
MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
|
||||
*)
|
||||
MISSING="\${SHELL} $am_aux_dir/missing" ;;
|
||||
esac
|
||||
fi
|
||||
# Use eval to expand $SHELL
|
||||
if eval "$MISSING --is-lightweight"; then
|
||||
am_missing_run="$MISSING "
|
||||
else
|
||||
am_missing_run=
|
||||
AC_MSG_WARN(['missing' script is too old or missing])
|
||||
fi
|
||||
])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_MANGLE_OPTION(NAME)
|
||||
# -----------------------
|
||||
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||
|
||||
# _AM_SET_OPTION(NAME)
|
||||
# --------------------
|
||||
# Set option NAME. Presently that only means defining a flag for this option.
|
||||
AC_DEFUN([_AM_SET_OPTION],
|
||||
[m4_define(_AM_MANGLE_OPTION([$1]), [1])])
|
||||
|
||||
# _AM_SET_OPTIONS(OPTIONS)
|
||||
# ------------------------
|
||||
# OPTIONS is a space-separated list of Automake options.
|
||||
AC_DEFUN([_AM_SET_OPTIONS],
|
||||
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||
|
||||
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||
# -------------------------------------------
|
||||
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||
AC_DEFUN([_AM_IF_OPTION],
|
||||
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_CC_C_O
|
||||
# ---------------
|
||||
# Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC
|
||||
# to automatically call this.
|
||||
AC_DEFUN([_AM_PROG_CC_C_O],
|
||||
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||
AC_REQUIRE_AUX_FILE([compile])dnl
|
||||
AC_LANG_PUSH([C])dnl
|
||||
AC_CACHE_CHECK(
|
||||
[whether $CC understands -c and -o together],
|
||||
[am_cv_prog_cc_c_o],
|
||||
[AC_LANG_CONFTEST([AC_LANG_PROGRAM([])])
|
||||
# Make sure it works both with $CC and with simple cc.
|
||||
# Following AC_PROG_CC_C_O, we do the test twice because some
|
||||
# compilers refuse to overwrite an existing .o file with -o,
|
||||
# though they will create one.
|
||||
am_cv_prog_cc_c_o=yes
|
||||
for am_i in 1 2; do
|
||||
if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \
|
||||
&& test -f conftest2.$ac_objext; then
|
||||
: OK
|
||||
else
|
||||
am_cv_prog_cc_c_o=no
|
||||
break
|
||||
fi
|
||||
done
|
||||
rm -f core conftest*
|
||||
unset am_i])
|
||||
if test "$am_cv_prog_cc_c_o" != yes; then
|
||||
# Losing compiler, so override with the script.
|
||||
# FIXME: It is wrong to rewrite CC.
|
||||
# But if we don't then we get into trouble of one sort or another.
|
||||
# A longer-term fix would be to have automake use am__CC in this case,
|
||||
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
|
||||
CC="$am_aux_dir/compile $CC"
|
||||
fi
|
||||
AC_LANG_POP([C])])
|
||||
|
||||
# For backward compatibility.
|
||||
AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
|
||||
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_RUN_LOG(COMMAND)
|
||||
# -------------------
|
||||
# Run COMMAND, save the exit status in ac_status, and log it.
|
||||
# (This has been adapted from Autoconf's _AC_RUN_LOG macro.)
|
||||
AC_DEFUN([AM_RUN_LOG],
|
||||
[{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD
|
||||
($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
|
||||
(exit $ac_status); }])
|
||||
|
||||
# Check to make sure that the build environment is sane. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 1996-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SANITY_CHECK
|
||||
# ---------------
|
||||
AC_DEFUN([AM_SANITY_CHECK],
|
||||
[AC_MSG_CHECKING([whether build environment is sane])
|
||||
# Reject unsafe characters in $srcdir or the absolute working directory
|
||||
# name. Accept space and tab only in the latter.
|
||||
am_lf='
|
||||
'
|
||||
case `pwd` in
|
||||
*[[\\\"\#\$\&\'\`$am_lf]]*)
|
||||
AC_MSG_ERROR([unsafe absolute working directory name]);;
|
||||
esac
|
||||
case $srcdir in
|
||||
*[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
|
||||
AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);;
|
||||
esac
|
||||
|
||||
# Do 'set' in a subshell so we don't clobber the current shell's
|
||||
# arguments. Must try -L first in case configure is actually a
|
||||
# symlink; some systems play weird games with the mod time of symlinks
|
||||
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||
# directory).
|
||||
if (
|
||||
am_has_slept=no
|
||||
for am_try in 1 2; do
|
||||
echo "timestamp, slept: $am_has_slept" > conftest.file
|
||||
set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
|
||||
if test "$[*]" = "X"; then
|
||||
# -L didn't work.
|
||||
set X `ls -t "$srcdir/configure" conftest.file`
|
||||
fi
|
||||
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||
|
||||
# If neither matched, then we have a broken ls. This can happen
|
||||
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||
# broken ls alias from the environment. This has actually
|
||||
# happened. Such a system could not be considered "sane".
|
||||
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||
alias in your environment])
|
||||
fi
|
||||
if test "$[2]" = conftest.file || test $am_try -eq 2; then
|
||||
break
|
||||
fi
|
||||
# Just in case.
|
||||
sleep 1
|
||||
am_has_slept=yes
|
||||
done
|
||||
test "$[2]" = conftest.file
|
||||
)
|
||||
then
|
||||
# Ok.
|
||||
:
|
||||
else
|
||||
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||
Check your system clock])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
# If we didn't sleep, we still need to ensure time stamps of config.status and
|
||||
# generated files are strictly newer.
|
||||
am_sleep_pid=
|
||||
if grep 'slept: no' conftest.file >/dev/null 2>&1; then
|
||||
( sleep 1 ) &
|
||||
am_sleep_pid=$!
|
||||
fi
|
||||
AC_CONFIG_COMMANDS_PRE(
|
||||
[AC_MSG_CHECKING([that generated files are newer than configure])
|
||||
if test -n "$am_sleep_pid"; then
|
||||
# Hide warnings about reused PIDs.
|
||||
wait $am_sleep_pid 2>/dev/null
|
||||
fi
|
||||
AC_MSG_RESULT([done])])
|
||||
rm -f conftest.file
|
||||
])
|
||||
|
||||
# Copyright (C) 2009-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_SILENT_RULES([DEFAULT])
|
||||
# --------------------------
|
||||
# Enable less verbose build rules; with the default set to DEFAULT
|
||||
# ("yes" being less verbose, "no" or empty being verbose).
|
||||
AC_DEFUN([AM_SILENT_RULES],
|
||||
[AC_ARG_ENABLE([silent-rules], [dnl
|
||||
AS_HELP_STRING(
|
||||
[--enable-silent-rules],
|
||||
[less verbose build output (undo: "make V=1")])
|
||||
AS_HELP_STRING(
|
||||
[--disable-silent-rules],
|
||||
[verbose build output (undo: "make V=0")])dnl
|
||||
])
|
||||
case $enable_silent_rules in @%:@ (((
|
||||
yes) AM_DEFAULT_VERBOSITY=0;;
|
||||
no) AM_DEFAULT_VERBOSITY=1;;
|
||||
*) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);;
|
||||
esac
|
||||
dnl
|
||||
dnl A few 'make' implementations (e.g., NonStop OS and NextStep)
|
||||
dnl do not support nested variable expansions.
|
||||
dnl See automake bug#9928 and bug#10237.
|
||||
am_make=${MAKE-make}
|
||||
AC_CACHE_CHECK([whether $am_make supports nested variables],
|
||||
[am_cv_make_support_nested_variables],
|
||||
[if AS_ECHO([['TRUE=$(BAR$(V))
|
||||
BAR0=false
|
||||
BAR1=true
|
||||
V=1
|
||||
am__doit:
|
||||
@$(TRUE)
|
||||
.PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then
|
||||
am_cv_make_support_nested_variables=yes
|
||||
else
|
||||
am_cv_make_support_nested_variables=no
|
||||
fi])
|
||||
if test $am_cv_make_support_nested_variables = yes; then
|
||||
dnl Using '$V' instead of '$(V)' breaks IRIX make.
|
||||
AM_V='$(V)'
|
||||
AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
|
||||
else
|
||||
AM_V=$AM_DEFAULT_VERBOSITY
|
||||
AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
|
||||
fi
|
||||
AC_SUBST([AM_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_V])dnl
|
||||
AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
|
||||
AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
|
||||
AM_BACKSLASH='\'
|
||||
AC_SUBST([AM_BACKSLASH])dnl
|
||||
_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
|
||||
])
|
||||
|
||||
# Copyright (C) 2001-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# AM_PROG_INSTALL_STRIP
|
||||
# ---------------------
|
||||
# One issue with vendor 'install' (even GNU) is that you can't
|
||||
# specify the program used to strip binaries. This is especially
|
||||
# annoying in cross-compiling environments, where the build's strip
|
||||
# is unlikely to handle the host's binaries.
|
||||
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||
# always use install-sh in "make install-strip", and initialize
|
||||
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||
# Installed binaries are usually stripped using 'strip' when the user
|
||||
# run "make install-strip". However 'strip' might not be the right
|
||||
# tool to use in cross-compilation environments, therefore Automake
|
||||
# will honor the 'STRIP' environment variable to overrule this program.
|
||||
dnl Don't test for $cross_compiling = yes, because it might be 'maybe'.
|
||||
if test "$cross_compiling" != no; then
|
||||
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||
fi
|
||||
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
|
||||
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||
|
||||
# Copyright (C) 2006-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# ---------------------------
|
||||
# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
|
||||
# This macro is traced by Automake.
|
||||
AC_DEFUN([_AM_SUBST_NOTMAKE])
|
||||
|
||||
# AM_SUBST_NOTMAKE(VARIABLE)
|
||||
# --------------------------
|
||||
# Public sister of _AM_SUBST_NOTMAKE.
|
||||
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
|
||||
|
||||
# Check how to create a tarball. -*- Autoconf -*-
|
||||
|
||||
# Copyright (C) 2004-2017 Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# _AM_PROG_TAR(FORMAT)
|
||||
# --------------------
|
||||
# Check how to create a tarball in format FORMAT.
|
||||
# FORMAT should be one of 'v7', 'ustar', or 'pax'.
|
||||
#
|
||||
# Substitute a variable $(am__tar) that is a command
|
||||
# writing to stdout a FORMAT-tarball containing the directory
|
||||
# $tardir.
|
||||
# tardir=directory && $(am__tar) > result.tar
|
||||
#
|
||||
# Substitute a variable $(am__untar) that extract such
|
||||
# a tarball read from stdin.
|
||||
# $(am__untar) < result.tar
|
||||
#
|
||||
AC_DEFUN([_AM_PROG_TAR],
|
||||
[# Always define AMTAR for backward compatibility. Yes, it's still used
|
||||
# in the wild :-( We should find a proper way to deprecate it ...
|
||||
AC_SUBST([AMTAR], ['$${TAR-tar}'])
|
||||
|
||||
# We'll loop over all known methods to create a tar archive until one works.
|
||||
_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
|
||||
|
||||
m4_if([$1], [v7],
|
||||
[am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
|
||||
|
||||
[m4_case([$1],
|
||||
[ustar],
|
||||
[# The POSIX 1988 'ustar' format is defined with fixed-size fields.
|
||||
# There is notably a 21 bits limit for the UID and the GID. In fact,
|
||||
# the 'pax' utility can hang on bigger UID/GID (see automake bug#8343
|
||||
# and bug#13588).
|
||||
am_max_uid=2097151 # 2^21 - 1
|
||||
am_max_gid=$am_max_uid
|
||||
# The $UID and $GID variables are not portable, so we need to resort
|
||||
# to the POSIX-mandated id(1) utility. Errors in the 'id' calls
|
||||
# below are definitely unexpected, so allow the users to see them
|
||||
# (that is, avoid stderr redirection).
|
||||
am_uid=`id -u || echo unknown`
|
||||
am_gid=`id -g || echo unknown`
|
||||
AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format])
|
||||
if test $am_uid -le $am_max_uid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi
|
||||
AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format])
|
||||
if test $am_gid -le $am_max_gid; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
_am_tools=none
|
||||
fi],
|
||||
|
||||
[pax],
|
||||
[],
|
||||
|
||||
[m4_fatal([Unknown tar format])])
|
||||
|
||||
AC_MSG_CHECKING([how to create a $1 tar archive])
|
||||
|
||||
# Go ahead even if we have the value already cached. We do so because we
|
||||
# need to set the values for the 'am__tar' and 'am__untar' variables.
|
||||
_am_tools=${am_cv_prog_tar_$1-$_am_tools}
|
||||
|
||||
for _am_tool in $_am_tools; do
|
||||
case $_am_tool in
|
||||
gnutar)
|
||||
for _am_tar in tar gnutar gtar; do
|
||||
AM_RUN_LOG([$_am_tar --version]) && break
|
||||
done
|
||||
am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
|
||||
am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
|
||||
am__untar="$_am_tar -xf -"
|
||||
;;
|
||||
plaintar)
|
||||
# Must skip GNU tar: if it does not support --format= it doesn't create
|
||||
# ustar tarball either.
|
||||
(tar --version) >/dev/null 2>&1 && continue
|
||||
am__tar='tar chf - "$$tardir"'
|
||||
am__tar_='tar chf - "$tardir"'
|
||||
am__untar='tar xf -'
|
||||
;;
|
||||
pax)
|
||||
am__tar='pax -L -x $1 -w "$$tardir"'
|
||||
am__tar_='pax -L -x $1 -w "$tardir"'
|
||||
am__untar='pax -r'
|
||||
;;
|
||||
cpio)
|
||||
am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
|
||||
am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
|
||||
am__untar='cpio -i -H $1 -d'
|
||||
;;
|
||||
none)
|
||||
am__tar=false
|
||||
am__tar_=false
|
||||
am__untar=false
|
||||
;;
|
||||
esac
|
||||
|
||||
# If the value was cached, stop now. We just wanted to have am__tar
|
||||
# and am__untar set.
|
||||
test -n "${am_cv_prog_tar_$1}" && break
|
||||
|
||||
# tar/untar a dummy directory, and stop if the command works.
|
||||
rm -rf conftest.dir
|
||||
mkdir conftest.dir
|
||||
echo GrepMe > conftest.dir/file
|
||||
AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
|
||||
rm -rf conftest.dir
|
||||
if test -s conftest.tar; then
|
||||
AM_RUN_LOG([$am__untar <conftest.tar])
|
||||
AM_RUN_LOG([cat conftest.dir/file])
|
||||
grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
|
||||
fi
|
||||
done
|
||||
rm -rf conftest.dir
|
||||
|
||||
AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
|
||||
AC_MSG_RESULT([$am_cv_prog_tar_$1])])
|
||||
|
||||
AC_SUBST([am__tar])
|
||||
AC_SUBST([am__untar])
|
||||
]) # _AM_PROG_TAR
|
||||
|
||||
m4_include([config/lead-dot.m4])
|
||||
m4_include([config/libtool.m4])
|
||||
m4_include([config/ltoptions.m4])
|
||||
m4_include([config/ltsugar.m4])
|
||||
m4_include([config/ltversion.m4])
|
||||
m4_include([config/lt~obsolete.m4])
|
||||
m4_include([config/multi.m4])
|
||||
m4_include([config/override.m4])
|
||||
m4_include([config/unwind_ipinfo.m4])
|
||||
m4_include([config/warnings.m4])
|
167
deps/libbacktrace/alloc.c
vendored
167
deps/libbacktrace/alloc.c
vendored
@ -1,167 +0,0 @@
|
||||
/* alloc.c -- Memory allocation without mmap.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* Allocation routines to use on systems that do not support anonymous
|
||||
mmap. This implementation just uses malloc, which means that the
|
||||
backtrace functions may not be safely invoked from a signal
|
||||
handler. */
|
||||
|
||||
/* Allocate memory like malloc. If ERROR_CALLBACK is NULL, don't
|
||||
report an error. */
|
||||
|
||||
void *
|
||||
backtrace_alloc (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
size_t size, backtrace_error_callback error_callback,
|
||||
void *data)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
ret = malloc (size);
|
||||
if (ret == NULL)
|
||||
{
|
||||
if (error_callback)
|
||||
error_callback (data, "malloc", errno);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Free memory. */
|
||||
|
||||
void
|
||||
backtrace_free (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
void *p, size_t size ATTRIBUTE_UNUSED,
|
||||
backtrace_error_callback error_callback ATTRIBUTE_UNUSED,
|
||||
void *data ATTRIBUTE_UNUSED)
|
||||
{
|
||||
free (p);
|
||||
}
|
||||
|
||||
/* Grow VEC by SIZE bytes. */
|
||||
|
||||
void *
|
||||
backtrace_vector_grow (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
size_t size, backtrace_error_callback error_callback,
|
||||
void *data, struct backtrace_vector *vec)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (size > vec->alc)
|
||||
{
|
||||
size_t alc;
|
||||
void *base;
|
||||
|
||||
if (vec->size == 0)
|
||||
alc = 32 * size;
|
||||
else if (vec->size >= 4096)
|
||||
alc = vec->size + 4096;
|
||||
else
|
||||
alc = 2 * vec->size;
|
||||
|
||||
if (alc < vec->size + size)
|
||||
alc = vec->size + size;
|
||||
|
||||
base = realloc (vec->base, alc);
|
||||
if (base == NULL)
|
||||
{
|
||||
error_callback (data, "realloc", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
vec->base = base;
|
||||
vec->alc = alc - vec->size;
|
||||
}
|
||||
|
||||
ret = (char *) vec->base + vec->size;
|
||||
vec->size += size;
|
||||
vec->alc -= size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Finish the current allocation on VEC. */
|
||||
|
||||
void *
|
||||
backtrace_vector_finish (struct backtrace_state *state,
|
||||
struct backtrace_vector *vec,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
/* With this allocator we call realloc in backtrace_vector_grow,
|
||||
which means we can't easily reuse the memory here. So just
|
||||
release it. */
|
||||
if (!backtrace_vector_release (state, vec, error_callback, data))
|
||||
return NULL;
|
||||
ret = vec->base;
|
||||
vec->base = NULL;
|
||||
vec->size = 0;
|
||||
vec->alc = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Release any extra space allocated for VEC. */
|
||||
|
||||
int
|
||||
backtrace_vector_release (struct backtrace_state *state ATTRIBUTE_UNUSED,
|
||||
struct backtrace_vector *vec,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data)
|
||||
{
|
||||
vec->alc = 0;
|
||||
|
||||
if (vec->size == 0)
|
||||
{
|
||||
/* As of C17, realloc with size 0 is marked as an obsolescent feature, use
|
||||
free instead. */
|
||||
free (vec->base);
|
||||
vec->base = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
vec->base = realloc (vec->base, vec->size);
|
||||
if (vec->base == NULL)
|
||||
{
|
||||
error_callback (data, "realloc", errno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
136
deps/libbacktrace/allocfail.c
vendored
136
deps/libbacktrace/allocfail.c
vendored
@ -1,136 +0,0 @@
|
||||
/* allocfail.c -- Test for libbacktrace library
|
||||
Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "filenames.h"
|
||||
|
||||
#include "backtrace.h"
|
||||
#include "backtrace-supported.h"
|
||||
|
||||
#include "testlib.h"
|
||||
|
||||
extern uint64_t get_nr_allocs (void);
|
||||
extern void set_fail_at_alloc (uint64_t);
|
||||
extern int at_fail_alloc_p (void);
|
||||
|
||||
static int test1 (void) __attribute__ ((noinline, unused));
|
||||
static int f2 (int) __attribute__ ((noinline));
|
||||
static int f3 (int, int) __attribute__ ((noinline));
|
||||
|
||||
static unsigned callback_errors = 0;
|
||||
|
||||
static void
|
||||
error_callback_full (void *vdata ATTRIBUTE_UNUSED,
|
||||
const char *msg ATTRIBUTE_UNUSED,
|
||||
int errnum ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (at_fail_alloc_p ())
|
||||
{
|
||||
set_fail_at_alloc (0);
|
||||
return;
|
||||
}
|
||||
|
||||
callback_errors++;
|
||||
}
|
||||
|
||||
static int
|
||||
callback_full (void *vdata ATTRIBUTE_UNUSED, uintptr_t pc ATTRIBUTE_UNUSED,
|
||||
const char *filename ATTRIBUTE_UNUSED,
|
||||
int lineno ATTRIBUTE_UNUSED,
|
||||
const char *function ATTRIBUTE_UNUSED)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
test1 (void)
|
||||
{
|
||||
return f2 (__LINE__) + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
f2 (int f1line)
|
||||
{
|
||||
return f3 (f1line, __LINE__) + 2;
|
||||
}
|
||||
|
||||
static int
|
||||
f3 (int f1line ATTRIBUTE_UNUSED, int f2line ATTRIBUTE_UNUSED)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = backtrace_full (state, 0, callback_full, error_callback_full, NULL);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr, "test1: unexpected return value %d\n", i);
|
||||
++failures;
|
||||
}
|
||||
|
||||
if (callback_errors)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/* Run all the tests. */
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
uint64_t fail_at = 0;
|
||||
|
||||
if (argc == 2)
|
||||
{
|
||||
fail_at = atoi (argv[1]);
|
||||
set_fail_at_alloc (fail_at);
|
||||
}
|
||||
|
||||
state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
|
||||
error_callback_full, NULL);
|
||||
if (state == NULL)
|
||||
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
|
||||
#if BACKTRACE_SUPPORTED
|
||||
test1 ();
|
||||
#endif
|
||||
|
||||
if (argc == 1)
|
||||
fprintf (stderr, "%llu\n", (long long unsigned) get_nr_allocs ());
|
||||
|
||||
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
104
deps/libbacktrace/allocfail.sh
vendored
104
deps/libbacktrace/allocfail.sh
vendored
@ -1,104 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
# allocfail.sh -- Test for libbacktrace library.
|
||||
# Copyright (C) 2018-2021 Free Software Foundation, Inc.
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
|
||||
# (1) Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
|
||||
# (2) Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
|
||||
# (3) The name of the author may not be used to
|
||||
# endorse or promote products derived from this software without
|
||||
# specific prior written permission.
|
||||
|
||||
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
set -e
|
||||
|
||||
if [ ! -f ./allocfail ]; then
|
||||
# Hard failure.
|
||||
exit 99
|
||||
fi
|
||||
|
||||
allocs=$(./allocfail 2>&1)
|
||||
if [ "$allocs" = "" ]; then
|
||||
# Hard failure.
|
||||
exit 99
|
||||
fi
|
||||
|
||||
# This generates the following output:
|
||||
# ...
|
||||
# $ allocfail.sh
|
||||
# allocs: 80495
|
||||
# Status changed to 0 at 1
|
||||
# Status changed to 1 at 3
|
||||
# Status changed to 0 at 11
|
||||
# Status changed to 1 at 12
|
||||
# Status changed to 0 at 845
|
||||
# ...
|
||||
#
|
||||
# We have status 0 for an allocation failure at:
|
||||
# - 1 because backtrace_create_state handles failure robustly
|
||||
# - 2 because the fail switches backtrace_full to !can_alloc mode.
|
||||
# - 11 because failure of elf_open_debugfile_by_buildid does not generate an
|
||||
# error callback beyond the one for the allocation failure itself.
|
||||
|
||||
echo "allocs: $allocs"
|
||||
|
||||
step=1
|
||||
i=1
|
||||
passes=0
|
||||
prev_status=-1
|
||||
while [ $i -le $allocs ]; do
|
||||
if ./allocfail $i >/dev/null 2>&1; status=$?; then
|
||||
true
|
||||
fi
|
||||
if [ $status -gt 1 ]; then
|
||||
echo "Unallowed fail found: $i"
|
||||
# Failure.
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The test-case would run too long if we would excercise all allocs.
|
||||
# So, run with step 1 initially, and increase the step once we have 10
|
||||
# subsequent passes, and drop back to step 1 once we encounter another
|
||||
# failure. This takes ~2.6 seconds on an i7-6600U CPU @ 2.60GHz.
|
||||
if [ $status -eq 0 ]; then
|
||||
passes=$(($passes + 1))
|
||||
if [ $passes -ge 10 ]; then
|
||||
step=$((step * 10))
|
||||
passes=0
|
||||
fi
|
||||
elif [ $status -eq 1 ]; then
|
||||
passes=0
|
||||
step=1
|
||||
fi
|
||||
|
||||
if [ $status -ne $prev_status ]; then
|
||||
echo "Status changed to $status at $i"
|
||||
fi
|
||||
prev_status=$status
|
||||
|
||||
i=$(($i + $step))
|
||||
done
|
||||
|
||||
# Success.
|
||||
exit 0
|
113
deps/libbacktrace/atomic.c
vendored
113
deps/libbacktrace/atomic.c
vendored
@ -1,113 +0,0 @@
|
||||
/* atomic.c -- Support for atomic functions if not present.
|
||||
Copyright (C) 2013-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "backtrace.h"
|
||||
#include "backtrace-supported.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* This file holds implementations of the atomic functions that are
|
||||
used if the host compiler has the sync functions but not the atomic
|
||||
functions, as is true of versions of GCC before 4.7. */
|
||||
|
||||
#if !defined (HAVE_ATOMIC_FUNCTIONS) && defined (HAVE_SYNC_FUNCTIONS)
|
||||
|
||||
/* Do an atomic load of a pointer. */
|
||||
|
||||
void *
|
||||
backtrace_atomic_load_pointer (void *arg)
|
||||
{
|
||||
void **pp;
|
||||
void *p;
|
||||
|
||||
pp = (void **) arg;
|
||||
p = *pp;
|
||||
while (!__sync_bool_compare_and_swap (pp, p, p))
|
||||
p = *pp;
|
||||
return p;
|
||||
}
|
||||
|
||||
/* Do an atomic load of an int. */
|
||||
|
||||
int
|
||||
backtrace_atomic_load_int (int *p)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = *p;
|
||||
while (!__sync_bool_compare_and_swap (p, i, i))
|
||||
i = *p;
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Do an atomic store of a pointer. */
|
||||
|
||||
void
|
||||
backtrace_atomic_store_pointer (void *arg, void *p)
|
||||
{
|
||||
void **pp;
|
||||
void *old;
|
||||
|
||||
pp = (void **) arg;
|
||||
old = *pp;
|
||||
while (!__sync_bool_compare_and_swap (pp, old, p))
|
||||
old = *pp;
|
||||
}
|
||||
|
||||
/* Do an atomic store of a size_t value. */
|
||||
|
||||
void
|
||||
backtrace_atomic_store_size_t (size_t *p, size_t v)
|
||||
{
|
||||
size_t old;
|
||||
|
||||
old = *p;
|
||||
while (!__sync_bool_compare_and_swap (p, old, v))
|
||||
old = *p;
|
||||
}
|
||||
|
||||
/* Do an atomic store of a int value. */
|
||||
|
||||
void
|
||||
backtrace_atomic_store_int (int *p, int v)
|
||||
{
|
||||
size_t old;
|
||||
|
||||
old = *p;
|
||||
while (!__sync_bool_compare_and_swap (p, old, v))
|
||||
old = *p;
|
||||
}
|
||||
|
||||
#endif
|
66
deps/libbacktrace/backtrace-supported.h.in
vendored
66
deps/libbacktrace/backtrace-supported.h.in
vendored
@ -1,66 +0,0 @@
|
||||
/* backtrace-supported.h.in -- Whether stack backtrace is supported.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* The file backtrace-supported.h.in is used by configure to generate
|
||||
the file backtrace-supported.h. The file backtrace-supported.h may
|
||||
be #include'd to see whether the backtrace library will be able to
|
||||
get a backtrace and produce symbolic information. */
|
||||
|
||||
|
||||
/* BACKTRACE_SUPPORTED will be #define'd as 1 if the backtrace library
|
||||
should work, 0 if it will not. Libraries may #include this to make
|
||||
other arrangements. */
|
||||
|
||||
#define BACKTRACE_SUPPORTED @BACKTRACE_SUPPORTED@
|
||||
|
||||
/* BACKTRACE_USES_MALLOC will be #define'd as 1 if the backtrace
|
||||
library will call malloc as it works, 0 if it will call mmap
|
||||
instead. This may be used to determine whether it is safe to call
|
||||
the backtrace functions from a signal handler. In general this
|
||||
only applies to calls like backtrace and backtrace_pcinfo. It does
|
||||
not apply to backtrace_simple, which never calls malloc. It does
|
||||
not apply to backtrace_print, which always calls fprintf and
|
||||
therefore malloc. */
|
||||
|
||||
#define BACKTRACE_USES_MALLOC @BACKTRACE_USES_MALLOC@
|
||||
|
||||
/* BACKTRACE_SUPPORTS_THREADS will be #define'd as 1 if the backtrace
|
||||
library is configured with threading support, 0 if not. If this is
|
||||
0, the threaded parameter to backtrace_create_state must be passed
|
||||
as 0. */
|
||||
|
||||
#define BACKTRACE_SUPPORTS_THREADS @BACKTRACE_SUPPORTS_THREADS@
|
||||
|
||||
/* BACKTRACE_SUPPORTS_DATA will be #defined'd as 1 if the backtrace_syminfo
|
||||
will work for variables. It will always work for functions. */
|
||||
|
||||
#define BACKTRACE_SUPPORTS_DATA @BACKTRACE_SUPPORTS_DATA@
|
129
deps/libbacktrace/backtrace.c
vendored
129
deps/libbacktrace/backtrace.c
vendored
@ -1,129 +0,0 @@
|
||||
/* backtrace.c -- Entry point for stack backtrace library.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "unwind.h"
|
||||
#include "backtrace.h"
|
||||
#include "internal.h"
|
||||
|
||||
/* The main backtrace_full routine. */
|
||||
|
||||
/* Data passed through _Unwind_Backtrace. */
|
||||
|
||||
struct backtrace_data
|
||||
{
|
||||
/* Number of frames to skip. */
|
||||
int skip;
|
||||
/* Library state. */
|
||||
struct backtrace_state *state;
|
||||
/* Callback routine. */
|
||||
backtrace_full_callback callback;
|
||||
/* Error callback routine. */
|
||||
backtrace_error_callback error_callback;
|
||||
/* Data to pass to callback routines. */
|
||||
void *data;
|
||||
/* Value to return from backtrace_full. */
|
||||
int ret;
|
||||
/* Whether there is any memory available. */
|
||||
int can_alloc;
|
||||
};
|
||||
|
||||
/* Unwind library callback routine. This is passed to
|
||||
_Unwind_Backtrace. */
|
||||
|
||||
static _Unwind_Reason_Code
|
||||
unwind (struct _Unwind_Context *context, void *vdata)
|
||||
{
|
||||
struct backtrace_data *bdata = (struct backtrace_data *) vdata;
|
||||
uintptr_t pc;
|
||||
int ip_before_insn = 0;
|
||||
|
||||
#ifdef HAVE_GETIPINFO
|
||||
pc = _Unwind_GetIPInfo (context, &ip_before_insn);
|
||||
#else
|
||||
pc = _Unwind_GetIP (context);
|
||||
#endif
|
||||
|
||||
if (bdata->skip > 0)
|
||||
{
|
||||
--bdata->skip;
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
if (!ip_before_insn)
|
||||
--pc;
|
||||
|
||||
if (!bdata->can_alloc)
|
||||
bdata->ret = bdata->callback (bdata->data, pc, NULL, 0, NULL);
|
||||
else
|
||||
bdata->ret = backtrace_pcinfo (bdata->state, pc, bdata->callback,
|
||||
bdata->error_callback, bdata->data);
|
||||
if (bdata->ret != 0)
|
||||
return _URC_END_OF_STACK;
|
||||
|
||||
return _URC_NO_REASON;
|
||||
}
|
||||
|
||||
/* Get a stack backtrace. */
|
||||
|
||||
int __attribute__((noinline))
|
||||
backtrace_full (struct backtrace_state *state, int skip,
|
||||
backtrace_full_callback callback,
|
||||
backtrace_error_callback error_callback, void *data)
|
||||
{
|
||||
struct backtrace_data bdata;
|
||||
void *p;
|
||||
|
||||
bdata.skip = skip + 1;
|
||||
bdata.state = state;
|
||||
bdata.callback = callback;
|
||||
bdata.error_callback = error_callback;
|
||||
bdata.data = data;
|
||||
bdata.ret = 0;
|
||||
|
||||
/* If we can't allocate any memory at all, don't try to produce
|
||||
file/line information. */
|
||||
p = backtrace_alloc (state, 4096, NULL, NULL);
|
||||
if (p == NULL)
|
||||
bdata.can_alloc = 0;
|
||||
else
|
||||
{
|
||||
backtrace_free (state, p, 4096, NULL, NULL);
|
||||
bdata.can_alloc = 1;
|
||||
}
|
||||
|
||||
_Unwind_Backtrace (unwind, &bdata);
|
||||
return bdata.ret;
|
||||
}
|
189
deps/libbacktrace/backtrace.h
vendored
189
deps/libbacktrace/backtrace.h
vendored
@ -1,189 +0,0 @@
|
||||
/* backtrace.h -- Public header file for stack backtrace library.
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
#ifndef BACKTRACE_H
|
||||
#define BACKTRACE_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The backtrace state. This struct is intentionally not defined in
|
||||
the public interface. */
|
||||
|
||||
struct backtrace_state;
|
||||
|
||||
/* The type of the error callback argument to backtrace functions.
|
||||
This function, if not NULL, will be called for certain error cases.
|
||||
The DATA argument is passed to the function that calls this one.
|
||||
The MSG argument is an error message. The ERRNUM argument, if
|
||||
greater than 0, holds an errno value. The MSG buffer may become
|
||||
invalid after this function returns.
|
||||
|
||||
As a special case, the ERRNUM argument will be passed as -1 if no
|
||||
debug info can be found for the executable, or if the debug info
|
||||
exists but has an unsupported version, but the function requires
|
||||
debug info (e.g., backtrace_full, backtrace_pcinfo). The MSG in
|
||||
this case will be something along the lines of "no debug info".
|
||||
Similarly, ERRNUM will be passed as -1 if there is no symbol table,
|
||||
but the function requires a symbol table (e.g., backtrace_syminfo).
|
||||
This may be used as a signal that some other approach should be
|
||||
tried. */
|
||||
|
||||
typedef void (*backtrace_error_callback) (void *data, const char *msg,
|
||||
int errnum);
|
||||
|
||||
/* Create state information for the backtrace routines. This must be
|
||||
called before any of the other routines, and its return value must
|
||||
be passed to all of the other routines. FILENAME is the path name
|
||||
of the executable file; if it is NULL the library will try
|
||||
system-specific path names. If not NULL, FILENAME must point to a
|
||||
permanent buffer. If THREADED is non-zero the state may be
|
||||
accessed by multiple threads simultaneously, and the library will
|
||||
use appropriate atomic operations. If THREADED is zero the state
|
||||
may only be accessed by one thread at a time. This returns a state
|
||||
pointer on success, NULL on error. If an error occurs, this will
|
||||
call the ERROR_CALLBACK routine.
|
||||
|
||||
Calling this function allocates resources that cannot be freed.
|
||||
There is no backtrace_free_state function. The state is used to
|
||||
cache information that is expensive to recompute. Programs are
|
||||
expected to call this function at most once and to save the return
|
||||
value for all later calls to backtrace functions. */
|
||||
|
||||
extern struct backtrace_state *backtrace_create_state (
|
||||
const char *filename, int threaded,
|
||||
backtrace_error_callback error_callback, void *data);
|
||||
|
||||
/* The type of the callback argument to the backtrace_full function.
|
||||
DATA is the argument passed to backtrace_full. PC is the program
|
||||
counter. FILENAME is the name of the file containing PC, or NULL
|
||||
if not available. LINENO is the line number in FILENAME containing
|
||||
PC, or 0 if not available. FUNCTION is the name of the function
|
||||
containing PC, or NULL if not available. This should return 0 to
|
||||
continuing tracing. The FILENAME and FUNCTION buffers may become
|
||||
invalid after this function returns. */
|
||||
|
||||
typedef int (*backtrace_full_callback) (void *data, uintptr_t pc,
|
||||
const char *filename, int lineno,
|
||||
const char *function);
|
||||
|
||||
/* Get a full stack backtrace. SKIP is the number of frames to skip;
|
||||
passing 0 will start the trace with the function calling
|
||||
backtrace_full. DATA is passed to the callback routine. If any
|
||||
call to CALLBACK returns a non-zero value, the stack backtrace
|
||||
stops, and backtrace returns that value; this may be used to limit
|
||||
the number of stack frames desired. If all calls to CALLBACK
|
||||
return 0, backtrace returns 0. The backtrace_full function will
|
||||
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||
function requires debug info for the executable. */
|
||||
|
||||
extern int backtrace_full (struct backtrace_state *state, int skip,
|
||||
backtrace_full_callback callback,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data);
|
||||
|
||||
/* The type of the callback argument to the backtrace_simple function.
|
||||
DATA is the argument passed to simple_backtrace. PC is the program
|
||||
counter. This should return 0 to continue tracing. */
|
||||
|
||||
typedef int (*backtrace_simple_callback) (void *data, uintptr_t pc);
|
||||
|
||||
/* Get a simple backtrace. SKIP is the number of frames to skip, as
|
||||
in backtrace. DATA is passed to the callback routine. If any call
|
||||
to CALLBACK returns a non-zero value, the stack backtrace stops,
|
||||
and backtrace_simple returns that value. Otherwise
|
||||
backtrace_simple returns 0. The backtrace_simple function will
|
||||
make at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||
function does not require any debug info for the executable. */
|
||||
|
||||
extern int backtrace_simple (struct backtrace_state *state, int skip,
|
||||
backtrace_simple_callback callback,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data);
|
||||
|
||||
/* Print the current backtrace in a user readable format to a FILE.
|
||||
SKIP is the number of frames to skip, as in backtrace_full. Any
|
||||
error messages are printed to stderr. This function requires debug
|
||||
info for the executable. */
|
||||
|
||||
extern void backtrace_print (struct backtrace_state *state, int skip, FILE *);
|
||||
|
||||
/* Given PC, a program counter in the current program, call the
|
||||
callback function with filename, line number, and function name
|
||||
information. This will normally call the callback function exactly
|
||||
once. However, if the PC happens to describe an inlined call, and
|
||||
the debugging information contains the necessary information, then
|
||||
this may call the callback function multiple times. This will make
|
||||
at least one call to either CALLBACK or ERROR_CALLBACK. This
|
||||
returns the first non-zero value returned by CALLBACK, or 0. */
|
||||
|
||||
extern int backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
|
||||
backtrace_full_callback callback,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data);
|
||||
|
||||
/* The type of the callback argument to backtrace_syminfo. DATA and
|
||||
PC are the arguments passed to backtrace_syminfo. SYMNAME is the
|
||||
name of the symbol for the corresponding code. SYMVAL is the
|
||||
value and SYMSIZE is the size of the symbol. SYMNAME will be NULL
|
||||
if no error occurred but the symbol could not be found. */
|
||||
|
||||
typedef void (*backtrace_syminfo_callback) (void *data, uintptr_t pc,
|
||||
const char *symname,
|
||||
uintptr_t symval,
|
||||
uintptr_t symsize);
|
||||
|
||||
/* Given ADDR, an address or program counter in the current program,
|
||||
call the callback information with the symbol name and value
|
||||
describing the function or variable in which ADDR may be found.
|
||||
This will call either CALLBACK or ERROR_CALLBACK exactly once.
|
||||
This returns 1 on success, 0 on failure. This function requires
|
||||
the symbol table but does not require the debug info. Note that if
|
||||
the symbol table is present but ADDR could not be found in the
|
||||
table, CALLBACK will be called with a NULL SYMNAME argument.
|
||||
Returns 1 on success, 0 on error. */
|
||||
|
||||
extern int backtrace_syminfo (struct backtrace_state *state, uintptr_t addr,
|
||||
backtrace_syminfo_callback callback,
|
||||
backtrace_error_callback error_callback,
|
||||
void *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* End extern "C". */
|
||||
#endif
|
||||
|
||||
#endif
|
501
deps/libbacktrace/btest.c
vendored
501
deps/libbacktrace/btest.c
vendored
@ -1,501 +0,0 @@
|
||||
/* btest.c -- Test for libbacktrace library
|
||||
Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor, Google.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
(1) Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
(2) Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
(3) The name of the author may not be used to
|
||||
endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE. */
|
||||
|
||||
/* This program tests the externally visible interfaces of the
|
||||
libbacktrace library. */
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "filenames.h"
|
||||
|
||||
#include "backtrace.h"
|
||||
#include "backtrace-supported.h"
|
||||
|
||||
#include "testlib.h"
|
||||
|
||||
/* Test the backtrace function with non-inlined functions. */
|
||||
|
||||
static int test1 (void) __attribute__ ((noinline, noclone, unused));
|
||||
static int f2 (int) __attribute__ ((noinline, noclone));
|
||||
static int f3 (int, int) __attribute__ ((noinline, noclone));
|
||||
|
||||
static int
|
||||
test1 (void)
|
||||
{
|
||||
/* Returning a value here and elsewhere avoids a tailcall which
|
||||
would mess up the backtrace. */
|
||||
return f2 (__LINE__) + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
f2 (int f1line)
|
||||
{
|
||||
return f3 (f1line, __LINE__) + 2;
|
||||
}
|
||||
|
||||
static int
|
||||
f3 (int f1line, int f2line)
|
||||
{
|
||||
struct info all[20];
|
||||
struct bdata data;
|
||||
int f3line;
|
||||
int i;
|
||||
|
||||
data.all = &all[0];
|
||||
data.index = 0;
|
||||
data.max = 20;
|
||||
data.failed = 0;
|
||||
|
||||
f3line = __LINE__ + 1;
|
||||
i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr, "test1: unexpected return value %d\n", i);
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
if (data.index < 3)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"test1: not enough frames; got %zu, expected at least 3\n",
|
||||
data.index);
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
check ("test1", 0, all, f3line, "f3", "btest.c", &data.failed);
|
||||
check ("test1", 1, all, f2line, "f2", "btest.c", &data.failed);
|
||||
check ("test1", 2, all, f1line, "test1", "btest.c", &data.failed);
|
||||
|
||||
printf ("%s: backtrace_full noinline\n", data.failed ? "FAIL" : "PASS");
|
||||
|
||||
if (data.failed)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/* Test the backtrace function with inlined functions. */
|
||||
|
||||
static inline int test2 (void) __attribute__ ((always_inline, unused));
|
||||
static inline int f12 (int) __attribute__ ((always_inline));
|
||||
static inline int f13 (int, int) __attribute__ ((always_inline));
|
||||
|
||||
static inline int
|
||||
test2 (void)
|
||||
{
|
||||
return f12 (__LINE__) + 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
f12 (int f1line)
|
||||
{
|
||||
return f13 (f1line, __LINE__) + 2;
|
||||
}
|
||||
|
||||
static inline int
|
||||
f13 (int f1line, int f2line)
|
||||
{
|
||||
struct info all[20];
|
||||
struct bdata data;
|
||||
int f3line;
|
||||
int i;
|
||||
|
||||
data.all = &all[0];
|
||||
data.index = 0;
|
||||
data.max = 20;
|
||||
data.failed = 0;
|
||||
|
||||
f3line = __LINE__ + 1;
|
||||
i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr, "test2: unexpected return value %d\n", i);
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
check ("test2", 0, all, f3line, "f13", "btest.c", &data.failed);
|
||||
check ("test2", 1, all, f2line, "f12", "btest.c", &data.failed);
|
||||
check ("test2", 2, all, f1line, "test2", "btest.c", &data.failed);
|
||||
|
||||
printf ("%s: backtrace_full inline\n", data.failed ? "FAIL" : "PASS");
|
||||
|
||||
if (data.failed)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/* Test the backtrace_simple function with non-inlined functions. */
|
||||
|
||||
static int test3 (void) __attribute__ ((noinline, noclone, unused));
|
||||
static int f22 (int) __attribute__ ((noinline, noclone));
|
||||
static int f23 (int, int) __attribute__ ((noinline, noclone));
|
||||
|
||||
static int
|
||||
test3 (void)
|
||||
{
|
||||
return f22 (__LINE__) + 1;
|
||||
}
|
||||
|
||||
static int
|
||||
f22 (int f1line)
|
||||
{
|
||||
return f23 (f1line, __LINE__) + 2;
|
||||
}
|
||||
|
||||
static int
|
||||
f23 (int f1line, int f2line)
|
||||
{
|
||||
uintptr_t addrs[20];
|
||||
struct sdata data;
|
||||
int f3line;
|
||||
int i;
|
||||
|
||||
data.addrs = &addrs[0];
|
||||
data.index = 0;
|
||||
data.max = 20;
|
||||
data.failed = 0;
|
||||
|
||||
f3line = __LINE__ + 1;
|
||||
i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr, "test3: unexpected return value %d\n", i);
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
if (!data.failed)
|
||||
{
|
||||
struct info all[20];
|
||||
struct bdata bdata;
|
||||
int j;
|
||||
|
||||
bdata.all = &all[0];
|
||||
bdata.index = 0;
|
||||
bdata.max = 20;
|
||||
bdata.failed = 0;
|
||||
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
i = backtrace_pcinfo (state, addrs[j], callback_one,
|
||||
error_callback_one, &bdata);
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
("test3: unexpected return value "
|
||||
"from backtrace_pcinfo %d\n"),
|
||||
i);
|
||||
bdata.failed = 1;
|
||||
}
|
||||
if (!bdata.failed && bdata.index != (size_t) (j + 1))
|
||||
{
|
||||
fprintf (stderr,
|
||||
("wrong number of calls from backtrace_pcinfo "
|
||||
"got %u expected %d\n"),
|
||||
(unsigned int) bdata.index, j + 1);
|
||||
bdata.failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
check ("test3", 0, all, f3line, "f23", "btest.c", &bdata.failed);
|
||||
check ("test3", 1, all, f2line, "f22", "btest.c", &bdata.failed);
|
||||
check ("test3", 2, all, f1line, "test3", "btest.c", &bdata.failed);
|
||||
|
||||
if (bdata.failed)
|
||||
data.failed = 1;
|
||||
|
||||
for (j = 0; j < 3; ++j)
|
||||
{
|
||||
struct symdata symdata;
|
||||
|
||||
symdata.name = NULL;
|
||||
symdata.val = 0;
|
||||
symdata.size = 0;
|
||||
symdata.failed = 0;
|
||||
|
||||
i = backtrace_syminfo (state, addrs[j], callback_three,
|
||||
error_callback_three, &symdata);
|
||||
if (i == 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
("test3: [%d]: unexpected return value "
|
||||
"from backtrace_syminfo %d\n"),
|
||||
j, i);
|
||||
symdata.failed = 1;
|
||||
}
|
||||
|
||||
if (!symdata.failed)
|
||||
{
|
||||
const char *expected;
|
||||
|
||||
switch (j)
|
||||
{
|
||||
case 0:
|
||||
expected = "f23";
|
||||
break;
|
||||
case 1:
|
||||
expected = "f22";
|
||||
break;
|
||||
case 2:
|
||||
expected = "test3";
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
if (symdata.name == NULL)
|
||||
{
|
||||
fprintf (stderr, "test3: [%d]: NULL syminfo name\n", j);
|
||||
symdata.failed = 1;
|
||||
}
|
||||
/* Use strncmp, not strcmp, because GCC might create a
|
||||
clone. */
|
||||
else if (strncmp (symdata.name, expected, strlen (expected))
|
||||
!= 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
("test3: [%d]: unexpected syminfo name "
|
||||
"got %s expected %s\n"),
|
||||
j, symdata.name, expected);
|
||||
symdata.failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (symdata.failed)
|
||||
data.failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("%s: backtrace_simple noinline\n", data.failed ? "FAIL" : "PASS");
|
||||
|
||||
if (data.failed)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/* Test the backtrace_simple function with inlined functions. */
|
||||
|
||||
static inline int test4 (void) __attribute__ ((always_inline, unused));
|
||||
static inline int f32 (int) __attribute__ ((always_inline));
|
||||
static inline int f33 (int, int) __attribute__ ((always_inline));
|
||||
|
||||
static inline int
|
||||
test4 (void)
|
||||
{
|
||||
return f32 (__LINE__) + 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
f32 (int f1line)
|
||||
{
|
||||
return f33 (f1line, __LINE__) + 2;
|
||||
}
|
||||
|
||||
static inline int
|
||||
f33 (int f1line, int f2line)
|
||||
{
|
||||
uintptr_t addrs[20];
|
||||
struct sdata data;
|
||||
int f3line;
|
||||
int i;
|
||||
|
||||
data.addrs = &addrs[0];
|
||||
data.index = 0;
|
||||
data.max = 20;
|
||||
data.failed = 0;
|
||||
|
||||
f3line = __LINE__ + 1;
|
||||
i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
|
||||
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr, "test3: unexpected return value %d\n", i);
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
if (!data.failed)
|
||||
{
|
||||
struct info all[20];
|
||||
struct bdata bdata;
|
||||
|
||||
bdata.all = &all[0];
|
||||
bdata.index = 0;
|
||||
bdata.max = 20;
|
||||
bdata.failed = 0;
|
||||
|
||||
i = backtrace_pcinfo (state, addrs[0], callback_one, error_callback_one,
|
||||
&bdata);
|
||||
if (i != 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
("test4: unexpected return value "
|
||||
"from backtrace_pcinfo %d\n"),
|
||||
i);
|
||||
bdata.failed = 1;
|
||||
}
|
||||
|
||||
check ("test4", 0, all, f3line, "f33", "btest.c", &bdata.failed);
|
||||
check ("test4", 1, all, f2line, "f32", "btest.c", &bdata.failed);
|
||||
check ("test4", 2, all, f1line, "test4", "btest.c", &bdata.failed);
|
||||
|
||||
if (bdata.failed)
|
||||
data.failed = 1;
|
||||
}
|
||||
|
||||
printf ("%s: backtrace_simple inline\n", data.failed ? "FAIL" : "PASS");
|
||||
|
||||
if (data.failed)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
static int test5 (void) __attribute__ ((unused));
|
||||
|
||||
int global = 1;
|
||||
|
||||
static int
|
||||
test5 (void)
|
||||
{
|
||||
struct symdata symdata;
|
||||
int i;
|
||||
uintptr_t addr = (uintptr_t) &global;
|
||||
|
||||
if (sizeof (global) > 1)
|
||||
addr += 1;
|
||||
|
||||
symdata.name = NULL;
|
||||
symdata.val = 0;
|
||||
symdata.size = 0;
|
||||
symdata.failed = 0;
|
||||
|
||||
i = backtrace_syminfo (state, addr, callback_three,
|
||||
error_callback_three, &symdata);
|
||||
if (i == 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"test5: unexpected return value from backtrace_syminfo %d\n",
|
||||
i);
|
||||
symdata.failed = 1;
|
||||
}
|
||||
|
||||
if (!symdata.failed)
|
||||
{
|
||||
if (symdata.name == NULL)
|
||||
{
|
||||
fprintf (stderr, "test5: NULL syminfo name\n");
|
||||
symdata.failed = 1;
|
||||
}
|
||||
else if (!(strncmp (symdata.name, "global", 6) == 0
|
||||
&& (symdata.name[6] == '\0'|| symdata.name[6] == '.')))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"test5: unexpected syminfo name got %s expected %s\n",
|
||||
symdata.name, "global");
|
||||
symdata.failed = 1;
|
||||
}
|
||||
else if (symdata.val != (uintptr_t) &global)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"test5: unexpected syminfo value got %lx expected %lx\n",
|
||||
(unsigned long) symdata.val,
|
||||
(unsigned long) (uintptr_t) &global);
|
||||
symdata.failed = 1;
|
||||
}
|
||||
else if (symdata.size != sizeof (global))
|
||||
{
|
||||
fprintf (stderr,
|
||||
"test5: unexpected syminfo size got %lx expected %lx\n",
|
||||
(unsigned long) symdata.size,
|
||||
(unsigned long) sizeof (global));
|
||||
symdata.failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf ("%s: backtrace_syminfo variable\n",
|
||||
symdata.failed ? "FAIL" : "PASS");
|
||||
|
||||
if (symdata.failed)
|
||||
++failures;
|
||||
|
||||
return failures;
|
||||
}
|
||||
|
||||
/* Check that are no files left open. */
|
||||
|
||||
static void
|
||||
check_open_files (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 3; i < 10; i++)
|
||||
{
|
||||
if (close (i) == 0)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"ERROR: descriptor %d still open after tests complete\n",
|
||||
i);
|
||||
++failures;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Run all the tests. */
|
||||
|
||||
int
|
||||
main (int argc ATTRIBUTE_UNUSED, char **argv)
|
||||
{
|
||||
state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
|
||||
error_callback_create, NULL);
|
||||
|
||||
#if BACKTRACE_SUPPORTED
|
||||
test1 ();
|
||||
test2 ();
|
||||
test3 ();
|
||||
test4 ();
|
||||
#if BACKTRACE_SUPPORTS_DATA
|
||||
test5 ();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
check_open_files ();
|
||||
|
||||
exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
348
deps/libbacktrace/compile
vendored
348
deps/libbacktrace/compile
vendored
@ -1,348 +0,0 @@
|
||||
#! /bin/sh
|
||||
# Wrapper for compilers which do not understand '-c -o'.
|
||||
|
||||
scriptversion=2016-01-11.22; # UTC
|
||||
|
||||
# Copyright (C) 1999-2017 Free Software Foundation, Inc.
|
||||
# Written by Tom Tromey <tromey@cygnus.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# This file is maintained in Automake, please report
|
||||
# bugs to <bug-automake@gnu.org> or send patches to
|
||||
# <automake-patches@gnu.org>.
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# We need space, tab and new line, in precisely that order. Quoting is
|
||||
# there to prevent tools from complaining about whitespace usage.
|
||||
IFS=" "" $nl"
|
||||
|
||||
file_conv=
|
||||
|
||||
# func_file_conv build_file lazy
|
||||
# Convert a $build file to $host form and store it in $file
|
||||
# Currently only supports Windows hosts. If the determined conversion
|
||||
# type is listed in (the comma separated) LAZY, no conversion will
|
||||
# take place.
|
||||
func_file_conv ()
|
||||
{
|
||||
file=$1
|
||||
case $file in
|
||||
/ | /[!/]*) # absolute file, and not a UNC file
|
||||
if test -z "$file_conv"; then
|
||||
# lazily determine how to convert abs files
|
||||
case `uname -s` in
|
||||
MINGW*)
|
||||
file_conv=mingw
|
||||
;;
|
||||
CYGWIN*)
|
||||
file_conv=cygwin
|
||||
;;
|
||||
*)
|
||||
file_conv=wine
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
case $file_conv/,$2, in
|
||||
*,$file_conv,*)
|
||||
;;
|
||||
mingw/*)
|
||||
file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
|
||||
;;
|
||||
cygwin/*)
|
||||
file=`cygpath -m "$file" || echo "$file"`
|
||||
;;
|
||||
wine/*)
|
||||
file=`winepath -w "$file" || echo "$file"`
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# func_cl_dashL linkdir
|
||||
# Make cl look for libraries in LINKDIR
|
||||
func_cl_dashL ()
|
||||
{
|
||||
func_file_conv "$1"
|
||||
if test -z "$lib_path"; then
|
||||
lib_path=$file
|
||||
else
|
||||
lib_path="$lib_path;$file"
|
||||
fi
|
||||
linker_opts="$linker_opts -LIBPATH:$file"
|
||||
}
|
||||
|
||||
# func_cl_dashl library
|
||||
# Do a library search-path lookup for cl
|
||||
func_cl_dashl ()
|
||||
{
|
||||
lib=$1
|
||||
found=no
|
||||
save_IFS=$IFS
|
||||
IFS=';'
|
||||
for dir in $lib_path $LIB
|
||||
do
|
||||
IFS=$save_IFS
|
||||
if $shared && test -f "$dir/$lib.dll.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.dll.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/$lib.lib"; then
|
||||
found=yes
|
||||
lib=$dir/$lib.lib
|
||||
break
|
||||
fi
|
||||
if test -f "$dir/lib$lib.a"; then
|
||||
found=yes
|
||||
lib=$dir/lib$lib.a
|
||||
break
|
||||
fi
|
||||
done
|
||||
IFS=$save_IFS
|
||||
|
||||
if test "$found" != yes; then
|
||||
lib=$lib.lib
|
||||
fi
|
||||
}
|
||||
|
||||
# func_cl_wrapper cl arg...
|
||||
# Adjust compile command to suit cl
|
||||
func_cl_wrapper ()
|
||||
{
|
||||
# Assume a capable shell
|
||||
lib_path=
|
||||
shared=:
|
||||
linker_opts=
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.[oO][bB][jJ])
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fo"$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
func_file_conv "$2"
|
||||
set x "$@" -Fe"$file"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-I)
|
||||
eat=1
|
||||
func_file_conv "$2" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-I*)
|
||||
func_file_conv "${1#-I}" mingw
|
||||
set x "$@" -I"$file"
|
||||
shift
|
||||
;;
|
||||
-l)
|
||||
eat=1
|
||||
func_cl_dashl "$2"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-l*)
|
||||
func_cl_dashl "${1#-l}"
|
||||
set x "$@" "$lib"
|
||||
shift
|
||||
;;
|
||||
-L)
|
||||
eat=1
|
||||
func_cl_dashL "$2"
|
||||
;;
|
||||
-L*)
|
||||
func_cl_dashL "${1#-L}"
|
||||
;;
|
||||
-static)
|
||||
shared=false
|
||||
;;
|
||||
-Wl,*)
|
||||
arg=${1#-Wl,}
|
||||
save_ifs="$IFS"; IFS=','
|
||||
for flag in $arg; do
|
||||
IFS="$save_ifs"
|
||||
linker_opts="$linker_opts $flag"
|
||||
done
|
||||
IFS="$save_ifs"
|
||||
;;
|
||||
-Xlinker)
|
||||
eat=1
|
||||
linker_opts="$linker_opts $2"
|
||||
;;
|
||||
-*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*.cc | *.CC | *.cxx | *.CXX | *.[cC]++)
|
||||
func_file_conv "$1"
|
||||
set x "$@" -Tp"$file"
|
||||
shift
|
||||
;;
|
||||
*.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO])
|
||||
func_file_conv "$1" mingw
|
||||
set x "$@" "$file"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
if test -n "$linker_opts"; then
|
||||
linker_opts="-link$linker_opts"
|
||||
fi
|
||||
exec "$@" $linker_opts
|
||||
exit 1
|
||||
}
|
||||
|
||||
eat=
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try '$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: compile [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Wrapper for compilers which do not understand '-c -o'.
|
||||
Remove '-o dest.o' from ARGS, run PROGRAM with the remaining
|
||||
arguments, and rename the output as expected.
|
||||
|
||||
If you are trying to build a whole package this is not the
|
||||
right script to run: please start by reading the file 'INSTALL'.
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "compile $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \
|
||||
icl | *[/\\]icl | icl.exe | *[/\\]icl.exe )
|
||||
func_cl_wrapper "$@" # Doesn't return...
|
||||
;;
|
||||
esac
|
||||
|
||||
ofile=
|
||||
cfile=
|
||||
|
||||
for arg
|
||||
do
|
||||
if test -n "$eat"; then
|
||||
eat=
|
||||
else
|
||||
case $1 in
|
||||
-o)
|
||||
# configure might choose to run compile as 'compile cc -o foo foo.c'.
|
||||
# So we strip '-o arg' only if arg is an object.
|
||||
eat=1
|
||||
case $2 in
|
||||
*.o | *.obj)
|
||||
ofile=$2
|
||||
;;
|
||||
*)
|
||||
set x "$@" -o "$2"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*.c)
|
||||
cfile=$1
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set x "$@" "$1"
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if test -z "$ofile" || test -z "$cfile"; then
|
||||
# If no '-o' option was seen then we might have been invoked from a
|
||||
# pattern rule where we don't need one. That is ok -- this is a
|
||||
# normal compilation that the losing compiler can handle. If no
|
||||
# '.c' file was seen then we are probably linking. That is also
|
||||
# ok.
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
# Name of file we expect compiler to create.
|
||||
cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'`
|
||||
|
||||
# Create the lock directory.
|
||||
# Note: use '[/\\:.-]' here to ensure that we don't use the same name
|
||||
# that we are using for the .o file. Also, base the name on the expected
|
||||
# object file name, since that is what matters with a parallel build.
|
||||
lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d
|
||||
while true; do
|
||||
if mkdir "$lockdir" >/dev/null 2>&1; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
# FIXME: race condition here if user kills between mkdir and trap.
|
||||
trap "rmdir '$lockdir'; exit 1" 1 2 15
|
||||
|
||||
# Run the compile.
|
||||
"$@"
|
||||
ret=$?
|
||||
|
||||
if test -f "$cofile"; then
|
||||
test "$cofile" = "$ofile" || mv "$cofile" "$ofile"
|
||||
elif test -f "${cofile}bj"; then
|
||||
test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile"
|
||||
fi
|
||||
|
||||
rmdir "$lockdir"
|
||||
exit $ret
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC0"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
1700
deps/libbacktrace/config.guess
vendored
1700
deps/libbacktrace/config.guess
vendored
File diff suppressed because it is too large
Load Diff
179
deps/libbacktrace/config.h.in
vendored
179
deps/libbacktrace/config.h.in
vendored
@ -1,179 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* ELF size: 32 or 64 */
|
||||
#undef BACKTRACE_ELF_SIZE
|
||||
|
||||
/* XCOFF size: 32 or 64 */
|
||||
#undef BACKTRACE_XCOFF_SIZE
|
||||
|
||||
/* Define to 1 if you have the __atomic functions */
|
||||
#undef HAVE_ATOMIC_FUNCTIONS
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `getpagesize', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_GETPAGESIZE
|
||||
|
||||
/* Define to 1 if you have the declaration of `strnlen', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_STRNLEN
|
||||
|
||||
/* Define to 1 if you have the declaration of `_pgmptr', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL__PGMPTR
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define if dl_iterate_phdr is available. */
|
||||
#undef HAVE_DL_ITERATE_PHDR
|
||||
|
||||
/* Define to 1 if you have the fcntl function */
|
||||
#undef HAVE_FCNTL
|
||||
|
||||
/* Define if getexecname is available. */
|
||||
#undef HAVE_GETEXECNAME
|
||||
|
||||
/* Define if _Unwind_GetIPInfo is available. */
|
||||
#undef HAVE_GETIPINFO
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have KERN_PROC and KERN_PROC_PATHNAME in <sys/sysctl.h>.
|
||||
*/
|
||||
#undef HAVE_KERN_PROC
|
||||
|
||||
/* Define to 1 if you have KERN_PROCARGS and KERN_PROC_PATHNAME in
|
||||
<sys/sysctl.h>. */
|
||||
#undef HAVE_KERN_PROC_ARGS
|
||||
|
||||
/* Define if -llzma is available. */
|
||||
#undef HAVE_LIBLZMA
|
||||
|
||||
/* Define to 1 if you have the <link.h> header file. */
|
||||
#undef HAVE_LINK_H
|
||||
|
||||
/* Define if AIX loadquery is available. */
|
||||
#undef HAVE_LOADQUERY
|
||||
|
||||
/* Define to 1 if you have the `lstat' function. */
|
||||
#undef HAVE_LSTAT
|
||||
|
||||
/* Define to 1 if you have the <mach-o/dyld.h> header file. */
|
||||
#undef HAVE_MACH_O_DYLD_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `readlink' function. */
|
||||
#undef HAVE_READLINK
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the __sync functions */
|
||||
#undef HAVE_SYNC_FUNCTIONS
|
||||
|
||||
/* Define to 1 if you have the <sys/ldr.h> header file. */
|
||||
#undef HAVE_SYS_LDR_H
|
||||
|
||||
/* Define to 1 if you have the <sys/link.h> header file. */
|
||||
#undef HAVE_SYS_LINK_H
|
||||
|
||||
/* Define to 1 if you have the <sys/mman.h> header file. */
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define if -lz is available. */
|
||||
#undef HAVE_ZLIB
|
||||
|
||||
/* Define if -lzstd is available. */
|
||||
#undef HAVE_ZSTD
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
# undef _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
# undef _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
# undef _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
# undef _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
# undef __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Enable large inode numbers on Mac OS X 10.5. */
|
||||
#ifndef _DARWIN_USE_64_BIT_INODE
|
||||
# define _DARWIN_USE_64_BIT_INODE 1
|
||||
#endif
|
||||
|
||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
||||
#undef _FILE_OFFSET_BITS
|
||||
|
||||
/* Define for large files, on AIX-style hosts. */
|
||||
#undef _LARGE_FILES
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#undef _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#undef _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#undef _POSIX_SOURCE
|
1885
deps/libbacktrace/config.sub
vendored
1885
deps/libbacktrace/config.sub
vendored
File diff suppressed because it is too large
Load Diff
38
deps/libbacktrace/config/enable.m4
vendored
38
deps/libbacktrace/config/enable.m4
vendored
@ -1,38 +0,0 @@
|
||||
dnl ----------------------------------------------------------------------
|
||||
dnl This whole bit snagged from libstdc++-v3.
|
||||
|
||||
dnl
|
||||
dnl GCC_ENABLE
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
|
||||
dnl (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
|
||||
dnl
|
||||
dnl See docs/html/17_intro/configury.html#enable for documentation.
|
||||
dnl
|
||||
AC_DEFUN([GCC_ENABLE],[dnl
|
||||
m4_define([_g_switch],[--enable-$1])dnl
|
||||
m4_define([_g_help],[AC_HELP_STRING(_g_switch$3,[$4 @<:@default=$2@:>@])])dnl
|
||||
AC_ARG_ENABLE($1,_g_help,
|
||||
m4_bmatch([$5],
|
||||
[^permit ],
|
||||
[[
|
||||
case "$enableval" in
|
||||
m4_bpatsubst([$5],[permit ])) ;;
|
||||
*) AC_MSG_ERROR(Unknown argument to enable/disable $1) ;;
|
||||
dnl Idea for future: generate a URL pointing to
|
||||
dnl "onlinedocs/configopts.html#whatever"
|
||||
esac
|
||||
]],
|
||||
[^$],
|
||||
[[
|
||||
case "$enableval" in
|
||||
yes|no) ;;
|
||||
*) AC_MSG_ERROR(Argument to enable/disable $1 must be yes or no) ;;
|
||||
esac
|
||||
]],
|
||||
[[$5]]),
|
||||
[enable_]m4_bpatsubst([$1],-,_)[=][$2])
|
||||
m4_undefine([_g_switch])dnl
|
||||
m4_undefine([_g_help])dnl
|
||||
])
|
||||
|
31
deps/libbacktrace/config/lead-dot.m4
vendored
31
deps/libbacktrace/config/lead-dot.m4
vendored
@ -1,31 +0,0 @@
|
||||
# -*- Autoconf -*-
|
||||
# Copyright (C) 2003, 2009 Free Software Foundation, Inc.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3, or (at your option)
|
||||
# any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING3. If not see
|
||||
# <http://www.gnu.org/licenses/>.
|
||||
|
||||
# serial 1
|
||||
|
||||
# Check whether the underlying file-system supports filenames
|
||||
# with a leading dot. For instance MS-DOS doesn't.
|
||||
AC_DEFUN([AM_SET_LEADING_DOT],
|
||||
[rm -rf .tst 2>/dev/null
|
||||
mkdir .tst 2>/dev/null
|
||||
if test -d .tst; then
|
||||
am__leading_dot=.
|
||||
else
|
||||
am__leading_dot=_
|
||||
fi
|
||||
rmdir .tst 2>/dev/null
|
||||
AC_SUBST([am__leading_dot])])
|
7436
deps/libbacktrace/config/libtool.m4
vendored
7436
deps/libbacktrace/config/libtool.m4
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user