mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
libstd: Rename libcore to libstd and libstd to libextra; update makefiles.
This only changes the directory names; it does not change the "real" metadata names.
This commit is contained in:
parent
565942b145
commit
0c820d4123
60
Makefile.in
60
Makefile.in
@ -205,8 +205,8 @@ define DEF_LIBS
|
||||
|
||||
CFG_RUNTIME_$(1) :=$(call CFG_LIB_NAME_$(1),rustrt)
|
||||
CFG_RUSTLLVM_$(1) :=$(call CFG_LIB_NAME_$(1),rustllvm)
|
||||
CFG_CORELIB_$(1) :=$(call CFG_LIB_NAME_$(1),core)
|
||||
CFG_STDLIB_$(1) :=$(call CFG_LIB_NAME_$(1),std)
|
||||
CFG_EXTRALIB_$(1) :=$(call CFG_LIB_NAME_$(1),extra)
|
||||
CFG_LIBRUSTC_$(1) :=$(call CFG_LIB_NAME_$(1),rustc)
|
||||
CFG_LIBSYNTAX_$(1) :=$(call CFG_LIB_NAME_$(1),syntax)
|
||||
CFG_LIBFUZZER_$(1) :=$(call CFG_LIB_NAME_$(1),fuzzer)
|
||||
@ -215,8 +215,8 @@ CFG_LIBRUSTDOC_$(1) :=$(call CFG_LIB_NAME_$(1),rustdoc)
|
||||
CFG_LIBRUSTI_$(1) :=$(call CFG_LIB_NAME_$(1),rusti)
|
||||
CFG_LIBRUST_$(1) :=$(call CFG_LIB_NAME_$(1),rust)
|
||||
|
||||
STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std)
|
||||
CORELIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),core)
|
||||
EXTRALIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),std)
|
||||
STDLIB_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),core)
|
||||
LIBRUSTC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustc)
|
||||
LIBSYNTAX_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),syntax)
|
||||
LIBFUZZER_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),fuzzer)
|
||||
@ -224,8 +224,8 @@ LIBRUSTPKG_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustpkg)
|
||||
LIBRUSTDOC_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rustdoc)
|
||||
LIBRUSTI_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rusti)
|
||||
LIBRUST_GLOB_$(1) :=$(call CFG_LIB_GLOB_$(1),rust)
|
||||
EXTRALIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),extra)
|
||||
STDLIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),std)
|
||||
CORELIB_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),core)
|
||||
LIBRUSTC_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),rustc)
|
||||
LIBSYNTAX_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),syntax)
|
||||
LIBFUZZER_DSYM_GLOB_$(1) :=$(call CFG_LIB_DSYM_GLOB_$(1),fuzzer)
|
||||
@ -239,20 +239,20 @@ endef
|
||||
$(foreach target,$(CFG_TARGET_TRIPLES),\
|
||||
$(eval $(call DEF_LIBS,$(target))))
|
||||
|
||||
######################################################################
|
||||
# Core library variables
|
||||
######################################################################
|
||||
|
||||
CORELIB_CRATE := $(S)src/libcore/core.rc
|
||||
CORELIB_INPUTS := $(wildcard $(addprefix $(S)src/libcore/, \
|
||||
core.rc *.rs */*.rs */*/*rs */*/*/*rs))
|
||||
|
||||
######################################################################
|
||||
# Standard library variables
|
||||
######################################################################
|
||||
|
||||
STDLIB_CRATE := $(S)src/libstd/std.rc
|
||||
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \
|
||||
STDLIB_CRATE := $(S)src/libstd/core.rc
|
||||
STDLIB_INPUTS := $(wildcard $(addprefix $(S)src/libstd/, \
|
||||
core.rc *.rs */*.rs */*/*rs */*/*/*rs))
|
||||
|
||||
######################################################################
|
||||
# Extra library variables
|
||||
######################################################################
|
||||
|
||||
EXTRALIB_CRATE := $(S)src/libextra/std.rc
|
||||
EXTRALIB_INPUTS := $(wildcard $(addprefix $(S)src/libextra/, \
|
||||
std.rc *.rs */*.rs))
|
||||
|
||||
######################################################################
|
||||
@ -344,33 +344,33 @@ TROOT$(1)_T_$(2)_H_$(3) = $$(HLIB$(1)_H_$(3))/rustc/$(2)
|
||||
TBIN$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/bin
|
||||
TLIB$(1)_T_$(2)_H_$(3) = $$(TROOT$(1)_T_$(2)_H_$(3))/$$(CFG_LIBDIR)
|
||||
|
||||
# The name of the core and standard libraries used by rustc
|
||||
# The name of the standard and extra libraries used by rustc
|
||||
ifdef CFG_DISABLE_SHAREDSTD
|
||||
HCORELIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/libcore.rlib
|
||||
TCORELIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/libcore.rlib
|
||||
|
||||
HSTDLIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/libstd.rlib
|
||||
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/libstd.rlib
|
||||
|
||||
HEXTRALIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/libextra.rlib
|
||||
TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/libextra.rlib
|
||||
|
||||
HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/librustc.rlib
|
||||
TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/librustc.rlib
|
||||
else
|
||||
HCORELIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_CORELIB_$(3))
|
||||
TCORELIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2))
|
||||
|
||||
HSTDLIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_STDLIB_$(3))
|
||||
TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
|
||||
|
||||
HEXTRALIB_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_EXTRALIB_$(3))
|
||||
TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
|
||||
|
||||
HLIBRUSTC_DEFAULT$(1)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTC_$(3))
|
||||
TLIBRUSTC_DEFAULT$(1)_T_$(2)_H_$(3) = \
|
||||
@ -382,8 +382,8 @@ HSREQ$(1)_H_$(3) = \
|
||||
$$(HBIN$(1)_H_$(3))/rustc$$(X_$(3)) \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_RUNTIME_$(3)) \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_RUSTLLVM_$(3)) \
|
||||
$$(HCORELIB_DEFAULT$(1)_H_$(3)) \
|
||||
$$(HSTDLIB_DEFAULT$(1)_H_$(3)) \
|
||||
$$(HEXTRALIB_DEFAULT$(1)_H_$(3)) \
|
||||
$$(HLIBSYNTAX_DEFAULT$(1)_H_$(3)) \
|
||||
$$(HLIBRUSTC_DEFAULT$(1)_H_$(3)) \
|
||||
$$(MKFILE_DEPS)
|
||||
@ -397,8 +397,8 @@ TSREQ$(1)_T_$(2)_H_$(3) = \
|
||||
# Prerequisites for a working stageN compiler and libraries, for a specific target
|
||||
SREQ$(1)_T_$(2)_H_$(3) = \
|
||||
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
|
||||
|
||||
# Prerequisites for a working stageN compiler and libraries, for a specific target
|
||||
CSREQ$(1)_T_$(2)_H_$(3) = \
|
||||
@ -413,8 +413,8 @@ CSREQ$(1)_T_$(2)_H_$(3) = \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTDOC_$(3)) \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUSTI_$(3)) \
|
||||
$$(HLIB$(1)_H_$(3))/$(CFG_LIBRUST_$(3)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBFUZZER_$(2)) \
|
||||
|
2
configure
vendored
2
configure
vendored
@ -643,7 +643,7 @@ fi
|
||||
step_msg "making directories"
|
||||
|
||||
for i in \
|
||||
doc doc/core doc/std \
|
||||
doc doc/std doc/extra \
|
||||
dl tmp
|
||||
do
|
||||
make_dir $i
|
||||
|
@ -73,14 +73,14 @@ clean$(1)_H_$(2):
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTPKG_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTDOC_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_RUNTIME_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_CORELIB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_STDLIB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_EXTRALIB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTC_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBSYNTAX_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUSTI_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CFG_LIBRUST_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(CORELIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(STDLIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(EXTRALIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBRUSTC_GLOB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBSYNTAX_GLOB_$(2))
|
||||
$(Q)rm -f $$(HLIB$(1)_H_$(2))/$(LIBFUZZER_GLOB_$(2))
|
||||
@ -111,14 +111,14 @@ clean$(1)_T_$(2)_H_$(3):
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTPKG_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTDOC_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTC_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUSTI_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBRUST_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(CORELIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(STDLIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(EXTRALIB_GLOB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBRUSTC_GLOB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBSYNTAX_GLOB_$(2))
|
||||
$(Q)rm -f $$(TLIB$(1)_T_$(2)_H_$(3))/$(LIBFUZZER_GLOB_$(2))
|
||||
|
@ -33,9 +33,9 @@ PKG_FILES := \
|
||||
compiletest \
|
||||
etc \
|
||||
libfuzzer \
|
||||
libcore \
|
||||
libsyntax \
|
||||
libextra \
|
||||
libstd \
|
||||
libsyntax \
|
||||
rt \
|
||||
librustdoc \
|
||||
rustllvm \
|
||||
|
@ -173,7 +173,7 @@ endif
|
||||
|
||||
|
||||
######################################################################
|
||||
# Rustdoc (libcore/std)
|
||||
# Rustdoc (libstd/extra)
|
||||
######################################################################
|
||||
|
||||
ifeq ($(CFG_PANDOC),)
|
||||
@ -199,8 +199,8 @@ doc/$(1)/rust.css: rust.css
|
||||
DOCS += doc/$(1)/index.html
|
||||
endef
|
||||
|
||||
$(eval $(call libdoc,core,$(CORELIB_CRATE),$(CORELIB_INPUTS)))
|
||||
$(eval $(call libdoc,std,$(STDLIB_CRATE),$(STDLIB_INPUTS)))
|
||||
$(eval $(call libdoc,extra,$(EXTRALIB_CRATE),$(EXTRALIB_INPUTS)))
|
||||
endif
|
||||
|
||||
|
||||
|
54
mk/host.mk
54
mk/host.mk
@ -28,8 +28,8 @@ $$(HBIN$(2)_H_$(4))/rustc$$(X_$(4)): \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)) \
|
||||
$$(HCORELIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
|
||||
| $$(HBIN$(2)_H_$(4))/
|
||||
|
||||
@$$(call E, cp: $$@)
|
||||
@ -40,8 +40,8 @@ $$(HLIB$(2)_H_$(4))/$(CFG_LIBRUSTC_$(4)): \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
|
||||
$$(HCORELIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
|
||||
@$$(call E, cp: $$@)
|
||||
@ -54,8 +54,8 @@ $$(HLIB$(2)_H_$(4))/$(CFG_LIBSYNTAX_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBSYNTAX_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUSTLLVM_$(4)) \
|
||||
$$(HCORELIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HSTDLIB_DEFAULT$(2)_H_$(4)) \
|
||||
$$(HEXTRALIB_DEFAULT$(2)_H_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
@ -69,44 +69,44 @@ $$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)): \
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_CORELIB_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
# Subtle: We do not let the shell expand $(CORELIB_DSYM_GLOB) directly rather
|
||||
# we use Make's $$(wildcard) facility. The reason is that, on mac, when using
|
||||
# USE_SNAPSHOT_CORELIB, we copy the core.dylib file out of the snapshot.
|
||||
# In that case, there is no .dSYM file. Annoyingly, bash then refuses to expand
|
||||
# glob, and cp reports an error because libcore-*.dylib.dsym does not exist.
|
||||
# Make instead expands the glob to nothing, which gives us the correct behavior.
|
||||
# (Copy .dsym file if it exists, but do nothing otherwise)
|
||||
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(CORELIB_GLOB_$(4)) \
|
||||
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(CORELIB_DSYM_GLOB_$(4))) \
|
||||
$$(HLIB$(2)_H_$(4))
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_CORELIB_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
# Subtle: We do not let the shell expand $(STDLIB_DSYM_GLOB) directly rather
|
||||
# we use Make's $$(wildcard) facility. The reason is that, on mac, when using
|
||||
# USE_SNAPSHOT_STDLIB, we copy the std.dylib file out of the snapshot.
|
||||
# In that case, there is no .dSYM file. Annoyingly, bash then refuses to expand
|
||||
# glob, and cp reports an error because libstd-*.dylib.dsym does not exist.
|
||||
# Make instead expands the glob to nothing, which gives us the correct behavior.
|
||||
# (Copy .dsym file if it exists, but do nothing otherwise)
|
||||
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_GLOB_$(4)) \
|
||||
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(STDLIB_DSYM_GLOB_$(4))) \
|
||||
$$(HLIB$(2)_H_$(4))
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/libcore.rlib: \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/libcore.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_EXTRALIB_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_STDLIB_$(4)) \
|
||||
$$(HLIB$(2)_H_$(4))/$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
$$(Q)cp -R $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_GLOB_$(4)) \
|
||||
$$(wildcard $$(TLIB$(1)_T_$(4)_H_$(3))/$(EXTRALIB_DSYM_GLOB_$(4))) \
|
||||
$$(HLIB$(2)_H_$(4))
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/libstd.rlib: \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/libstd.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/libstd.rlib: \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/libstd.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libcore.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libextra.rlib: \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/libextra.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libstd.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
@ -114,8 +114,8 @@ $$(HLIB$(2)_H_$(4))/libstd.rlib: \
|
||||
|
||||
$$(HLIB$(2)_H_$(4))/librustc.rlib: \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/librustc.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libcore.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libstd.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/libextra.rlib \
|
||||
$$(HLIB$(2)_H_$(4))/$$(CFG_RUNTIME_$(4)) \
|
||||
| $$(HLIB$(2)_H_$(4))/
|
||||
@$$(call E, cp: $$@)
|
||||
|
@ -52,10 +52,10 @@ define INSTALL_TARGET_N
|
||||
install-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
|
||||
$$(Q)mkdir -p $$(PTL$(1)$(2))
|
||||
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_RUNTIME_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CORELIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(STDLIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(EXTRALIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),libmorestack.a)
|
||||
|
||||
endef
|
||||
@ -64,10 +64,10 @@ define INSTALL_HOST_N
|
||||
install-target-$(1)-host-$(2): $$(CSREQ$$(ISTAGE)_T_$(1)_H_$(2))
|
||||
$$(Q)mkdir -p $$(PTL$(1)$(2))
|
||||
$$(Q)$$(call INSTALL_LIB,$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CFG_RUNTIME_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(CORELIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(STDLIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(EXTRALIB_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
$$(TL$(1)$(2)),$$(PTL$(1)$(2)),$$(LIBRUSTC_GLOB_$(1)))
|
||||
$$(Q)$$(call INSTALL_LIB, \
|
||||
@ -113,8 +113,8 @@ install-host: $(CSREQ$(ISTAGE)_T_$(CFG_BUILD_TRIPLE)_H_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rustdoc$(X_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rusti$(X_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL,$(HB2),$(PHB),rust$(X_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(CORELIB_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(EXTRALIB_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTC_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBSYNTAX_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
$(Q)$(call INSTALL_LIB,$(HL),$(PHL),$(LIBRUSTI_GLOB_$(CFG_BUILD_TRIPLE)))
|
||||
@ -141,8 +141,8 @@ uninstall:
|
||||
$(Q)rm -f $(PHL)/$(CFG_RUSTLLVM_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)rm -f $(PHL)/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)for i in \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(CORELIB_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(STDLIB_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(EXTRALIB_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTC_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBSYNTAX_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
$(call HOST_LIB_FROM_HL_GLOB,$(LIBRUSTPKG_GLOB_$(CFG_BUILD_TRIPLE))) \
|
||||
@ -203,16 +203,16 @@ define INSTALL_RUNTIME_TARGET_N
|
||||
install-runtime-target-$(1)-host-$(2): $$(TSREQ$$(ISTAGE)_T_$(1)_H_$(2)) $$(SREQ$$(ISTAGE)_T_$(1)_H_$(2))
|
||||
$(Q)$(call ADB_SHELL,mkdir,$(CFG_RUNTIME_PUSH_DIR))
|
||||
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CFG_RUNTIME_$(1)),$(CFG_RUNTIME_PUSH_DIR))
|
||||
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(CORELIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
|
||||
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(STDLIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
|
||||
$(Q)$(call ADB_PUSH,$$(TL$(1)$(2))/$$(EXTRALIB_GLOB_$(1)),$(CFG_RUNTIME_PUSH_DIR))
|
||||
endef
|
||||
|
||||
define INSTALL_RUNTIME_TARGET_CLEANUP_N
|
||||
install-runtime-target-$(1)-cleanup:
|
||||
$(Q)$(call ADB,remount)
|
||||
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CFG_RUNTIME_$(1)))
|
||||
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(CORELIB_GLOB_$(1)))
|
||||
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(STDLIB_GLOB_$(1)))
|
||||
$(Q)$(call ADB_SHELL,rm,$(CFG_RUNTIME_PUSH_DIR)/$(EXTRALIB_GLOB_$(1)))
|
||||
endef
|
||||
|
||||
$(eval $(call INSTALL_RUNTIME_TARGET_N,arm-linux-androideabi,$(CFG_BUILD_TRIPLE)))
|
||||
|
4
mk/pp.mk
4
mk/pp.mk
@ -12,8 +12,8 @@
|
||||
ifdef PPFILES
|
||||
PP_INPUTS_FILTERED := $(wildcard $(PPFILES))
|
||||
else
|
||||
PP_INPUTS = $(wildcard $(addprefix $(S)src/libcore/,*.rs */*.rs)) \
|
||||
$(wildcard $(addprefix $(S)src/libstd/,*.rs */*.rs)) \
|
||||
PP_INPUTS = $(wildcard $(addprefix $(S)src/libstd/,*.rs */*.rs)) \
|
||||
$(wildcard $(addprefix $(S)src/libextra/,*.rs */*.rs)) \
|
||||
$(wildcard $(addprefix $(S)src/rustc/,*.rs */*.rs */*/*.rs)) \
|
||||
$(wildcard $(S)src/test/*/*.rs \
|
||||
$(S)src/test/*/*/*.rs) \
|
||||
|
14
mk/stage0.mk
14
mk/stage0.mk
@ -25,11 +25,11 @@ $(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_RUNTIME_$(CFG_BUILD_TRIPLE)): \
|
||||
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)touch $@
|
||||
|
||||
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_CORELIB_$(CFG_BUILD_TRIPLE)): \
|
||||
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_STDLIB_$(CFG_BUILD_TRIPLE)): \
|
||||
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)touch $@
|
||||
|
||||
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_STDLIB_$(CFG_BUILD_TRIPLE)): \
|
||||
$(HLIB0_H_$(CFG_BUILD_TRIPLE))/$(CFG_EXTRALIB_$(CFG_BUILD_TRIPLE)): \
|
||||
$(HBIN0_H_$(CFG_BUILD_TRIPLE))/rustc$(X_$(CFG_BUILD_TRIPLE))
|
||||
$(Q)touch $@
|
||||
|
||||
@ -58,16 +58,16 @@ $$(HLIB0_H_$(1))/$(CFG_RUNTIME_$(1)): \
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
$$(HLIB0_H_$(1))/$(CFG_CORELIB_$(1)): \
|
||||
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_CORELIB_$(1))
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(CORELIB_GLOB_$(1)) $$@
|
||||
|
||||
$$(HLIB0_H_$(1))/$(CFG_STDLIB_$(1)): \
|
||||
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_STDLIB_$(1))
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(STDLIB_GLOB_$(1)) $$@
|
||||
|
||||
$$(HLIB0_H_$(1))/$(CFG_EXTRALIB_$(1)): \
|
||||
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_EXTRALIB_$(1))
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$(TLIB$(2)_T_$(1)_H_$(3))/$(EXTRALIB_GLOB_$(1)) $$@
|
||||
|
||||
$$(HLIB0_H_$(1))/$(CFG_LIBRUSTC_$(1)): \
|
||||
$$(TLIB$(2)_T_$(1)_H_$(3))/$(CFG_LIBRUSTC_$(1))
|
||||
@$$(call E, cp: $$@)
|
||||
|
14
mk/target.mk
14
mk/target.mk
@ -29,16 +29,16 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_RUNTIME_$(2)): \
|
||||
@$$(call E, cp: $$@)
|
||||
$$(Q)cp $$< $$@
|
||||
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2)): \
|
||||
$$(CORELIB_CRATE) $$(CORELIB_INPUTS) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
|
||||
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
|
||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
|
||||
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_CORELIB_$(2)) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_EXTRALIB_$(2)): \
|
||||
$$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)) \
|
||||
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
|
||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
@ -47,8 +47,8 @@ $$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_STDLIB_$(2)): \
|
||||
$$(TLIB$(1)_T_$(2)_H_$(3))/$(CFG_LIBSYNTAX_$(3)): \
|
||||
$$(LIBSYNTAX_CRATE) $$(LIBSYNTAX_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(2)_H_$(3)) \
|
||||
$$(TCORELIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
|
||||
$$(TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
|
||||
$$(TSTDLIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
|
||||
$$(TEXTRALIB_DEFAULT$(1)_T_$(2)_H_$(3)) \
|
||||
| $$(TLIB$(1)_T_$(2)_H_$(3))/
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) $(BORROWCK) -o $$@ $$< && touch $$@
|
||||
|
16
mk/tests.mk
16
mk/tests.mk
@ -14,7 +14,7 @@
|
||||
######################################################################
|
||||
|
||||
# The names of crates that must be tested
|
||||
TEST_TARGET_CRATES = core std
|
||||
TEST_TARGET_CRATES = std extra
|
||||
TEST_HOST_CRATES = syntax rustc rustdoc rusti rust rustpkg
|
||||
TEST_CRATES = $(TEST_TARGET_CRATES) $(TEST_HOST_CRATES)
|
||||
|
||||
@ -148,7 +148,7 @@ check-test: cleantestlibs cleantmptestlogs all check-stage2-rfail
|
||||
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
|
||||
|
||||
check-lite: cleantestlibs cleantmptestlogs \
|
||||
check-stage2-core check-stage2-std check-stage2-rpass \
|
||||
check-stage2-std check-stage2-extra check-stage2-rpass \
|
||||
check-stage2-rfail check-stage2-cfail
|
||||
$(Q)$(CFG_PYTHON) $(S)src/etc/check-summary.py tmp/*.log
|
||||
|
||||
@ -281,22 +281,22 @@ $(foreach host,$(CFG_HOST_TRIPLES), \
|
||||
|
||||
define TEST_RUNNER
|
||||
|
||||
# If NO_REBUILD is set then break the dependencies on std so we can
|
||||
# test crates without rebuilding core and std first
|
||||
# If NO_REBUILD is set then break the dependencies on extra so we can
|
||||
# test crates without rebuilding std and extra first
|
||||
ifeq ($(NO_REBUILD),)
|
||||
STDTESTDEP_$(1)_$(2)_$(3) = $$(TLIB$(1)_T_$(2)_H_$(3))/$$(CFG_STDLIB_$(2))
|
||||
else
|
||||
STDTESTDEP_$(1)_$(2)_$(3) =
|
||||
endif
|
||||
|
||||
$(3)/stage$(1)/test/coretest-$(2)$$(X_$(2)): \
|
||||
$$(CORELIB_CRATE) $$(CORELIB_INPUTS) \
|
||||
$(3)/stage$(1)/test/stdtest-$(2)$$(X_$(2)): \
|
||||
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
|
||||
$$(STDTESTDEP_$(1)_$(2)_$(3))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
||||
|
||||
$(3)/stage$(1)/test/stdtest-$(2)$$(X_$(2)): \
|
||||
$$(STDLIB_CRATE) $$(STDLIB_INPUTS) \
|
||||
$(3)/stage$(1)/test/extratest-$(2)$$(X_$(2)): \
|
||||
$$(EXTRALIB_CRATE) $$(EXTRALIB_INPUTS) \
|
||||
$$(STDTESTDEP_$(1)_$(2)_$(3))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(2)_H_$(3)) -o $$@ $$< --test
|
||||
|
14
mk/tools.mk
14
mk/tools.mk
@ -41,8 +41,8 @@ define TOOLS_STAGE_N_TARGET
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBFUZZER_$(4)): \
|
||||
$$(FUZZER_LIB) $$(FUZZER_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
@ -56,16 +56,16 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/fuzzer$$(X_$(4)): \
|
||||
$$(TBIN$(1)_T_$(4)_H_$(3))/compiletest$$(X_$(4)): \
|
||||
$$(COMPILETEST_CRATE) $$(COMPILETEST_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4))
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$<
|
||||
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)): \
|
||||
$$(RUSTPKG_LIB) $$(RUSTPKG_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
@ -79,8 +79,8 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustpkg$$(X_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)): \
|
||||
$$(RUSTDOC_LIB) $$(RUSTDOC_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
@ -94,8 +94,8 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rustdoc$$(X_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)): \
|
||||
$$(RUSTI_LIB) $$(RUSTI_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTC_$(4))
|
||||
@$$(call E, compile_and_link: $$@)
|
||||
$$(STAGE$(1)_T_$(4)_H_$(3)) -o $$@ $$< && touch $$@
|
||||
@ -109,8 +109,8 @@ $$(TBIN$(1)_T_$(4)_H_$(3))/rusti$$(X_$(4)): \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUST_$(4)): \
|
||||
$$(RUST_LIB) $$(RUST_INPUTS) \
|
||||
$$(TSREQ$(1)_T_$(4)_H_$(3)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_CORELIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_STDLIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_EXTRALIB_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTPKG_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTI_$(4)) \
|
||||
$$(TLIB$(1)_T_$(4)_H_$(3))/$(CFG_LIBRUSTDOC_$(4)) \
|
||||
|
@ -1,810 +0,0 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
Message passing
|
||||
*/
|
||||
|
||||
use cast::{transmute, transmute_mut};
|
||||
use container::Container;
|
||||
use either::{Either, Left, Right};
|
||||
use kinds::Owned;
|
||||
use option::{Option, Some, None};
|
||||
use uint;
|
||||
use vec;
|
||||
use vec::OwnedVector;
|
||||
use util::replace;
|
||||
use unstable::sync::{Exclusive, exclusive};
|
||||
use rtcomm = rt::comm;
|
||||
use rt;
|
||||
|
||||
use pipes::{wait_many, PacketHeader};
|
||||
|
||||
// FIXME #5160: Making this public exposes some plumbing from
|
||||
// pipes. Needs some refactoring
|
||||
pub use pipes::Selectable;
|
||||
|
||||
/// A trait for things that can send multiple messages.
|
||||
pub trait GenericChan<T> {
|
||||
/// Sends a message.
|
||||
fn send(&self, x: T);
|
||||
}
|
||||
|
||||
/// Things that can send multiple messages and can detect when the receiver
|
||||
/// is closed
|
||||
pub trait GenericSmartChan<T> {
|
||||
/// Sends a message, or report if the receiver has closed the connection.
|
||||
fn try_send(&self, x: T) -> bool;
|
||||
}
|
||||
|
||||
/// A trait for things that can receive multiple messages.
|
||||
pub trait GenericPort<T> {
|
||||
/// Receives a message, or fails if the connection closes.
|
||||
fn recv(&self) -> T;
|
||||
|
||||
/** Receives a message, or returns `none` if
|
||||
the connection is closed or closes.
|
||||
*/
|
||||
fn try_recv(&self) -> Option<T>;
|
||||
}
|
||||
|
||||
/// Ports that can `peek`
|
||||
pub trait Peekable<T> {
|
||||
/// Returns true if a message is available
|
||||
fn peek(&self) -> bool;
|
||||
}
|
||||
|
||||
/// An endpoint that can send many messages.
|
||||
pub struct Chan<T> {
|
||||
inner: Either<pipesy::Chan<T>, rtcomm::Chan<T>>
|
||||
}
|
||||
|
||||
/// An endpoint that can receive many messages.
|
||||
pub struct Port<T> {
|
||||
inner: Either<pipesy::Port<T>, rtcomm::Port<T>>
|
||||
}
|
||||
|
||||
/** Creates a `(Port, Chan)` pair.
|
||||
|
||||
These allow sending or receiving an unlimited number of messages.
|
||||
|
||||
*/
|
||||
pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
|
||||
let (port, chan) = match rt::context() {
|
||||
rt::OldTaskContext => match pipesy::stream() {
|
||||
(p, c) => (Left(p), Left(c))
|
||||
},
|
||||
_ => match rtcomm::stream() {
|
||||
(p, c) => (Right(p), Right(c))
|
||||
}
|
||||
};
|
||||
let port = Port { inner: port };
|
||||
let chan = Chan { inner: chan };
|
||||
return (port, chan);
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for Chan<T> {
|
||||
fn send(&self, x: T) {
|
||||
match self.inner {
|
||||
Left(ref chan) => chan.send(x),
|
||||
Right(ref chan) => chan.send(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
match self.inner {
|
||||
Left(ref chan) => chan.try_send(x),
|
||||
Right(ref chan) => chan.try_send(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericPort<T> for Port<T> {
|
||||
fn recv(&self) -> T {
|
||||
match self.inner {
|
||||
Left(ref port) => port.recv(),
|
||||
Right(ref port) => port.recv()
|
||||
}
|
||||
}
|
||||
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
match self.inner {
|
||||
Left(ref port) => port.try_recv(),
|
||||
Right(ref port) => port.try_recv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for Port<T> {
|
||||
fn peek(&self) -> bool {
|
||||
match self.inner {
|
||||
Left(ref port) => port.peek(),
|
||||
Right(ref port) => port.peek()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Selectable for Port<T> {
|
||||
fn header(&mut self) -> *mut PacketHeader {
|
||||
match self.inner {
|
||||
Left(ref mut port) => port.header(),
|
||||
Right(_) => fail!("can't select on newsched ports")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Treat many ports as one.
|
||||
#[unsafe_mut_field(ports)]
|
||||
pub struct PortSet<T> {
|
||||
ports: ~[pipesy::Port<T>],
|
||||
}
|
||||
|
||||
pub impl<T: Owned> PortSet<T> {
|
||||
fn new() -> PortSet<T> {
|
||||
PortSet {
|
||||
ports: ~[]
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&self, port: Port<T>) {
|
||||
let Port { inner } = port;
|
||||
let port = match inner {
|
||||
Left(p) => p,
|
||||
Right(_) => fail!("PortSet not implemented")
|
||||
};
|
||||
unsafe {
|
||||
let self_ports = transmute_mut(&self.ports);
|
||||
self_ports.push(port)
|
||||
}
|
||||
}
|
||||
|
||||
fn chan(&self) -> Chan<T> {
|
||||
let (po, ch) = stream();
|
||||
self.add(po);
|
||||
ch
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned> GenericPort<T> for PortSet<T> {
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
unsafe {
|
||||
let self_ports = transmute_mut(&self.ports);
|
||||
let mut result = None;
|
||||
// we have to swap the ports array so we aren't borrowing
|
||||
// aliasable mutable memory.
|
||||
let mut ports = replace(self_ports, ~[]);
|
||||
while result.is_none() && ports.len() > 0 {
|
||||
let i = wait_many(ports);
|
||||
match ports[i].try_recv() {
|
||||
Some(m) => {
|
||||
result = Some(m);
|
||||
}
|
||||
None => {
|
||||
// Remove this port.
|
||||
let _ = ports.swap_remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
*self_ports = ports;
|
||||
result
|
||||
}
|
||||
}
|
||||
fn recv(&self) -> T {
|
||||
self.try_recv().expect("port_set: endpoints closed")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for PortSet<T> {
|
||||
fn peek(&self) -> bool {
|
||||
// It'd be nice to use self.port.each, but that version isn't
|
||||
// pure.
|
||||
for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
|
||||
let port: &pipesy::Port<T> = &self.ports[i];
|
||||
if port.peek() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// A channel that can be shared between many senders.
|
||||
pub struct SharedChan<T> {
|
||||
ch: Exclusive<pipesy::Chan<T>>
|
||||
}
|
||||
|
||||
impl<T: Owned> SharedChan<T> {
|
||||
/// Converts a `chan` into a `shared_chan`.
|
||||
pub fn new(c: Chan<T>) -> SharedChan<T> {
|
||||
let Chan { inner } = c;
|
||||
let c = match inner {
|
||||
Left(c) => c,
|
||||
Right(_) => fail!("SharedChan not implemented")
|
||||
};
|
||||
SharedChan { ch: exclusive(c) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for SharedChan<T> {
|
||||
fn send(&self, x: T) {
|
||||
let mut xx = Some(x);
|
||||
do self.ch.with_imm |chan| {
|
||||
let x = replace(&mut xx, None);
|
||||
chan.send(x.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
let mut xx = Some(x);
|
||||
do self.ch.with_imm |chan| {
|
||||
let x = replace(&mut xx, None);
|
||||
chan.try_send(x.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> ::clone::Clone for SharedChan<T> {
|
||||
fn clone(&self) -> SharedChan<T> {
|
||||
SharedChan { ch: self.ch.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct PortOne<T> {
|
||||
inner: Either<pipesy::PortOne<T>, rtcomm::PortOne<T>>
|
||||
}
|
||||
|
||||
pub struct ChanOne<T> {
|
||||
inner: Either<pipesy::ChanOne<T>, rtcomm::ChanOne<T>>
|
||||
}
|
||||
|
||||
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
|
||||
let (port, chan) = match rt::context() {
|
||||
rt::OldTaskContext => match pipesy::oneshot() {
|
||||
(p, c) => (Left(p), Left(c)),
|
||||
},
|
||||
_ => match rtcomm::oneshot() {
|
||||
(p, c) => (Right(p), Right(c))
|
||||
}
|
||||
};
|
||||
let port = PortOne { inner: port };
|
||||
let chan = ChanOne { inner: chan };
|
||||
return (port, chan);
|
||||
}
|
||||
|
||||
impl<T: Owned> PortOne<T> {
|
||||
pub fn recv(self) -> T {
|
||||
let PortOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.recv(),
|
||||
Right(p) => p.recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_recv(self) -> Option<T> {
|
||||
let PortOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.try_recv(),
|
||||
Right(p) => p.try_recv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> ChanOne<T> {
|
||||
pub fn send(self, data: T) {
|
||||
let ChanOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.send(data),
|
||||
Right(p) => p.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_send(self, data: T) -> bool {
|
||||
let ChanOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.try_send(data),
|
||||
Right(p) => p.try_send(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn recv_one<T: Owned>(port: PortOne<T>) -> T {
|
||||
let PortOne { inner } = port;
|
||||
match inner {
|
||||
Left(p) => pipesy::recv_one(p),
|
||||
Right(p) => p.recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_recv_one<T: Owned>(port: PortOne<T>) -> Option<T> {
|
||||
let PortOne { inner } = port;
|
||||
match inner {
|
||||
Left(p) => pipesy::try_recv_one(p),
|
||||
Right(p) => p.try_recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) {
|
||||
let ChanOne { inner } = chan;
|
||||
match inner {
|
||||
Left(c) => pipesy::send_one(c, data),
|
||||
Right(c) => c.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
|
||||
let ChanOne { inner } = chan;
|
||||
match inner {
|
||||
Left(c) => pipesy::try_send_one(c, data),
|
||||
Right(c) => c.try_send(data)
|
||||
}
|
||||
}
|
||||
|
||||
mod pipesy {
|
||||
|
||||
use kinds::Owned;
|
||||
use option::{Option, Some, None};
|
||||
use pipes::{recv, try_recv, peek, PacketHeader};
|
||||
use super::{GenericChan, GenericSmartChan, GenericPort, Peekable, Selectable};
|
||||
use cast::transmute_mut;
|
||||
use util::replace;
|
||||
|
||||
/*proto! oneshot (
|
||||
Oneshot:send<T:Owned> {
|
||||
send(T) -> !
|
||||
}
|
||||
)*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod oneshot {
|
||||
priv use core::kinds::Owned;
|
||||
use ptr::to_mut_unsafe_ptr;
|
||||
|
||||
pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
|
||||
let buffer = ~::core::pipes::Buffer {
|
||||
header: ::core::pipes::BufferHeader(),
|
||||
data: __Buffer {
|
||||
Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>()
|
||||
},
|
||||
};
|
||||
do ::core::pipes::entangle_buffer(buffer) |buffer, data| {
|
||||
data.Oneshot.set_buffer(buffer);
|
||||
to_mut_unsafe_ptr(&mut data.Oneshot)
|
||||
}
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Oneshot<T> { pub send(T), }
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct __Buffer<T> {
|
||||
Oneshot: ::core::pipes::Packet<Oneshot<T>>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_send<T: Owned>(pipe: Oneshot<T>, x_0: T) ->
|
||||
::core::option::Option<()> {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(())
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn send<T: Owned>(pipe: Oneshot<T>, x_0: T) {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
::core::pipes::send(pipe, message);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::SendPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::RecvPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
}
|
||||
|
||||
/// The send end of a oneshot pipe.
|
||||
pub struct ChanOne<T> {
|
||||
contents: oneshot::client::Oneshot<T>
|
||||
}
|
||||
|
||||
impl<T> ChanOne<T> {
|
||||
pub fn new(contents: oneshot::client::Oneshot<T>) -> ChanOne<T> {
|
||||
ChanOne {
|
||||
contents: contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The receive end of a oneshot pipe.
|
||||
pub struct PortOne<T> {
|
||||
contents: oneshot::server::Oneshot<T>
|
||||
}
|
||||
|
||||
impl<T> PortOne<T> {
|
||||
pub fn new(contents: oneshot::server::Oneshot<T>) -> PortOne<T> {
|
||||
PortOne {
|
||||
contents: contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
|
||||
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
|
||||
let (chan, port) = oneshot::init();
|
||||
(PortOne::new(port), ChanOne::new(chan))
|
||||
}
|
||||
|
||||
pub impl<T: Owned> PortOne<T> {
|
||||
fn recv(self) -> T { recv_one(self) }
|
||||
fn try_recv(self) -> Option<T> { try_recv_one(self) }
|
||||
fn unwrap(self) -> oneshot::server::Oneshot<T> {
|
||||
match self {
|
||||
PortOne { contents: s } => s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T: Owned> ChanOne<T> {
|
||||
fn send(self, data: T) { send_one(self, data) }
|
||||
fn try_send(self, data: T) -> bool { try_send_one(self, data) }
|
||||
fn unwrap(self) -> oneshot::client::Oneshot<T> {
|
||||
match self {
|
||||
ChanOne { contents: s } => s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a oneshot pipe, failing if the connection was
|
||||
* closed.
|
||||
*/
|
||||
pub fn recv_one<T: Owned>(port: PortOne<T>) -> T {
|
||||
match port {
|
||||
PortOne { contents: port } => {
|
||||
let oneshot::send(message) = recv(port);
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a message from a oneshot pipe unless the connection was closed.
|
||||
pub fn try_recv_one<T: Owned> (port: PortOne<T>) -> Option<T> {
|
||||
match port {
|
||||
PortOne { contents: port } => {
|
||||
let message = try_recv(port);
|
||||
|
||||
if message.is_none() {
|
||||
None
|
||||
} else {
|
||||
let oneshot::send(message) = message.unwrap();
|
||||
Some(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a message on a oneshot pipe, failing if the connection was closed.
|
||||
pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) {
|
||||
match chan {
|
||||
ChanOne { contents: chan } => oneshot::client::send(chan, data),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message on a oneshot pipe, or return false if the connection was
|
||||
* closed.
|
||||
*/
|
||||
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
|
||||
match chan {
|
||||
ChanOne { contents: chan } => {
|
||||
oneshot::client::try_send(chan, data).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Streams - Make pipes a little easier in general.
|
||||
|
||||
/*proto! streamp (
|
||||
Open:send<T: Owned> {
|
||||
data(T) -> Open<T>
|
||||
}
|
||||
)*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod streamp {
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
pub fn init<T: Owned>() -> (client::Open<T>, server::Open<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
::core::pipes::entangle()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Open<T> { pub data(T, server::Open<T>), }
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_data<T: Owned>(pipe: Open<T>, x_0: T) ->
|
||||
::core::option::Option<Open<T>> {
|
||||
{
|
||||
use super::data;
|
||||
let (c, s) = ::core::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(c)
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn data<T: Owned>(pipe: Open<T>, x_0: T) -> Open<T> {
|
||||
{
|
||||
use super::data;
|
||||
let (c, s) = ::core::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
::core::pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::SendPacket<super::Open<T>>;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::RecvPacket<super::Open<T>>;
|
||||
}
|
||||
}
|
||||
|
||||
/// An endpoint that can send many messages.
|
||||
#[unsafe_mut_field(endp)]
|
||||
pub struct Chan<T> {
|
||||
endp: Option<streamp::client::Open<T>>
|
||||
}
|
||||
|
||||
/// An endpoint that can receive many messages.
|
||||
#[unsafe_mut_field(endp)]
|
||||
pub struct Port<T> {
|
||||
endp: Option<streamp::server::Open<T>>,
|
||||
}
|
||||
|
||||
/** Creates a `(Port, Chan)` pair.
|
||||
|
||||
These allow sending or receiving an unlimited number of messages.
|
||||
|
||||
*/
|
||||
pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
|
||||
let (c, s) = streamp::init();
|
||||
|
||||
(Port {
|
||||
endp: Some(s)
|
||||
}, Chan {
|
||||
endp: Some(c)
|
||||
})
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for Chan<T> {
|
||||
#[inline(always)]
|
||||
fn send(&self, x: T) {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
*self_endp = Some(streamp::client::data(endp.unwrap(), x))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
|
||||
#[inline(always)]
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
match streamp::client::try_data(endp.unwrap(), x) {
|
||||
Some(next) => {
|
||||
*self_endp = Some(next);
|
||||
true
|
||||
}
|
||||
None => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericPort<T> for Port<T> {
|
||||
#[inline(always)]
|
||||
fn recv(&self) -> T {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
let streamp::data(x, endp) = recv(endp.unwrap());
|
||||
*self_endp = Some(endp);
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
match try_recv(endp.unwrap()) {
|
||||
Some(streamp::data(x, endp)) => {
|
||||
*self_endp = Some(endp);
|
||||
Some(x)
|
||||
}
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for Port<T> {
|
||||
#[inline(always)]
|
||||
fn peek(&self) -> bool {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let mut endp = replace(self_endp, None);
|
||||
let peek = match endp {
|
||||
Some(ref mut endp) => peek(endp),
|
||||
None => fail!("peeking empty stream")
|
||||
};
|
||||
*self_endp = endp;
|
||||
peek
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Selectable for Port<T> {
|
||||
fn header(&mut self) -> *mut PacketHeader {
|
||||
match self.endp {
|
||||
Some(ref mut endp) => endp.header(),
|
||||
None => fail!("peeking empty stream")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Returns the index of an endpoint that is ready to receive.
|
||||
pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint {
|
||||
wait_many(endpoints)
|
||||
}
|
||||
|
||||
/// Returns 0 or 1 depending on which endpoint is ready to receive
|
||||
pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B)
|
||||
-> Either<(), ()> {
|
||||
let mut endpoints = [ a.header(), b.header() ];
|
||||
match wait_many(endpoints) {
|
||||
0 => Left(()),
|
||||
1 => Right(()),
|
||||
_ => fail!("wait returned unexpected index"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a message from one of two endpoints.
|
||||
pub trait Select2<T: Owned, U: Owned> {
|
||||
/// Receive a message or return `None` if a connection closes.
|
||||
fn try_select(&mut self) -> Either<Option<T>, Option<U>>;
|
||||
/// Receive a message or fail if a connection closes.
|
||||
fn select(&mut self) -> Either<T, U>;
|
||||
}
|
||||
|
||||
impl<T:Owned,
|
||||
U:Owned,
|
||||
Left:Selectable + GenericPort<T>,
|
||||
Right:Selectable + GenericPort<U>>
|
||||
Select2<T, U>
|
||||
for (Left, Right) {
|
||||
fn select(&mut self) -> Either<T, U> {
|
||||
// XXX: Bad borrow check workaround.
|
||||
unsafe {
|
||||
let this: &(Left, Right) = transmute(self);
|
||||
match *this {
|
||||
(ref lp, ref rp) => {
|
||||
let lp: &mut Left = transmute(lp);
|
||||
let rp: &mut Right = transmute(rp);
|
||||
match select2i(lp, rp) {
|
||||
Left(()) => Left(lp.recv()),
|
||||
Right(()) => Right(rp.recv()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_select(&mut self) -> Either<Option<T>, Option<U>> {
|
||||
// XXX: Bad borrow check workaround.
|
||||
unsafe {
|
||||
let this: &(Left, Right) = transmute(self);
|
||||
match *this {
|
||||
(ref lp, ref rp) => {
|
||||
let lp: &mut Left = transmute(lp);
|
||||
let rp: &mut Right = transmute(rp);
|
||||
match select2i(lp, rp) {
|
||||
Left(()) => Left (lp.try_recv()),
|
||||
Right(()) => Right(rp.try_recv()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use either::Right;
|
||||
use super::{Chan, Port, oneshot, stream};
|
||||
|
||||
#[test]
|
||||
fn test_select2() {
|
||||
let (p1, c1) = stream();
|
||||
let (p2, c2) = stream();
|
||||
|
||||
c1.send(~"abc");
|
||||
|
||||
let mut tuple = (p1, p2);
|
||||
match tuple.select() {
|
||||
Right(_) => fail!(),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
c2.send(123);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_oneshot() {
|
||||
let (p, c) = oneshot();
|
||||
|
||||
c.send(());
|
||||
|
||||
p.recv()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peek_terminated() {
|
||||
let (port, chan): (Port<int>, Chan<int>) = stream();
|
||||
|
||||
{
|
||||
// Destroy the channel
|
||||
let _chan = chan;
|
||||
}
|
||||
|
||||
assert!(!port.peek());
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
110
src/libextra/comm.rs
Normal file
110
src/libextra/comm.rs
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
|
||||
Higher level communication abstractions.
|
||||
|
||||
*/
|
||||
|
||||
use core::comm::{GenericChan, GenericSmartChan, GenericPort};
|
||||
use core::comm::{Chan, Port, Selectable, Peekable};
|
||||
use core::pipes;
|
||||
|
||||
/// An extension of `pipes::stream` that allows both sending and receiving.
|
||||
pub struct DuplexStream<T, U> {
|
||||
priv chan: Chan<T>,
|
||||
priv port: Port<U>,
|
||||
}
|
||||
|
||||
// Allow these methods to be used without import:
|
||||
pub impl<T:Owned,U:Owned> DuplexStream<T, U> {
|
||||
fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
}
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
self.chan.try_send(x)
|
||||
}
|
||||
fn recv(&self, ) -> U {
|
||||
self.port.recv()
|
||||
}
|
||||
fn try_recv(&self) -> Option<U> {
|
||||
self.port.try_recv()
|
||||
}
|
||||
fn peek(&self) -> bool {
|
||||
self.port.peek()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
|
||||
fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericSmartChan<T> for DuplexStream<T, U> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
self.chan.try_send(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
|
||||
fn recv(&self) -> U {
|
||||
self.port.recv()
|
||||
}
|
||||
|
||||
fn try_recv(&self) -> Option<U> {
|
||||
self.port.try_recv()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
|
||||
fn peek(&self) -> bool {
|
||||
self.port.peek()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
|
||||
fn header(&mut self) -> *mut pipes::PacketHeader {
|
||||
self.port.header()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a bidirectional stream.
|
||||
pub fn DuplexStream<T:Owned,U:Owned>()
|
||||
-> (DuplexStream<T, U>, DuplexStream<U, T>)
|
||||
{
|
||||
let (p1, c2) = comm::stream();
|
||||
let (p2, c1) = comm::stream();
|
||||
(DuplexStream {
|
||||
chan: c1,
|
||||
port: p1
|
||||
},
|
||||
DuplexStream {
|
||||
chan: c2,
|
||||
port: p2
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use comm::DuplexStream;
|
||||
|
||||
#[test]
|
||||
pub fn DuplexStream1() {
|
||||
let (left, right) = DuplexStream();
|
||||
|
||||
left.send(~"abc");
|
||||
right.send(123);
|
||||
|
||||
assert!(left.recv() == 123);
|
||||
assert!(right.recv() == ~"abc");
|
||||
}
|
||||
}
|
248
src/libextra/unicode.rs
Normal file
248
src/libextra/unicode.rs
Normal file
@ -0,0 +1,248 @@
|
||||
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#[forbid(deprecated_mode)];
|
||||
|
||||
pub mod icu {
|
||||
pub type UBool = u8;
|
||||
pub type UProperty = int;
|
||||
pub type UChar32 = char;
|
||||
|
||||
pub static TRUE : u8 = 1u8;
|
||||
pub static FALSE : u8 = 1u8;
|
||||
|
||||
pub static UCHAR_ALPHABETIC : UProperty = 0;
|
||||
pub static UCHAR_BINARY_START : UProperty = 0; // = UCHAR_ALPHABETIC
|
||||
pub static UCHAR_ASCII_HEX_DIGIT : UProperty = 1;
|
||||
pub static UCHAR_BIDI_CONTROL : UProperty = 2;
|
||||
|
||||
pub static UCHAR_BIDI_MIRRORED : UProperty = 3;
|
||||
pub static UCHAR_DASH : UProperty = 4;
|
||||
pub static UCHAR_DEFAULT_IGNORABLE_CODE_POINT : UProperty = 5;
|
||||
pub static UCHAR_DEPRECATED : UProperty = 6;
|
||||
|
||||
pub static UCHAR_DIACRITIC : UProperty = 7;
|
||||
pub static UCHAR_EXTENDER : UProperty = 8;
|
||||
pub static UCHAR_FULL_COMPOSITION_EXCLUSION : UProperty = 9;
|
||||
pub static UCHAR_GRAPHEME_BASE : UProperty = 10;
|
||||
|
||||
pub static UCHAR_GRAPHEME_EXTEND : UProperty = 11;
|
||||
pub static UCHAR_GRAPHEME_LINK : UProperty = 12;
|
||||
pub static UCHAR_HEX_DIGIT : UProperty = 13;
|
||||
pub static UCHAR_HYPHEN : UProperty = 14;
|
||||
|
||||
pub static UCHAR_ID_CONTINUE : UProperty = 15;
|
||||
pub static UCHAR_ID_START : UProperty = 16;
|
||||
pub static UCHAR_IDEOGRAPHIC : UProperty = 17;
|
||||
pub static UCHAR_IDS_BINARY_OPERATOR : UProperty = 18;
|
||||
|
||||
pub static UCHAR_IDS_TRINARY_OPERATOR : UProperty = 19;
|
||||
pub static UCHAR_JOIN_CONTROL : UProperty = 20;
|
||||
pub static UCHAR_LOGICAL_ORDER_EXCEPTION : UProperty = 21;
|
||||
pub static UCHAR_LOWERCASE : UProperty = 22;
|
||||
|
||||
pub static UCHAR_MATH : UProperty = 23;
|
||||
pub static UCHAR_NONCHARACTER_CODE_POINT : UProperty = 24;
|
||||
pub static UCHAR_QUOTATION_MARK : UProperty = 25;
|
||||
pub static UCHAR_RADICAL : UProperty = 26;
|
||||
|
||||
pub static UCHAR_SOFT_DOTTED : UProperty = 27;
|
||||
pub static UCHAR_TERMINAL_PUNCTUATION : UProperty = 28;
|
||||
pub static UCHAR_UNIFIED_IDEOGRAPH : UProperty = 29;
|
||||
pub static UCHAR_UPPERCASE : UProperty = 30;
|
||||
|
||||
pub static UCHAR_WHITE_SPACE : UProperty = 31;
|
||||
pub static UCHAR_XID_CONTINUE : UProperty = 32;
|
||||
pub static UCHAR_XID_START : UProperty = 33;
|
||||
pub static UCHAR_CASE_SENSITIVE : UProperty = 34;
|
||||
|
||||
pub static UCHAR_S_TERM : UProperty = 35;
|
||||
pub static UCHAR_VARIATION_SELECTOR : UProperty = 36;
|
||||
pub static UCHAR_NFD_INERT : UProperty = 37;
|
||||
pub static UCHAR_NFKD_INERT : UProperty = 38;
|
||||
|
||||
pub static UCHAR_NFC_INERT : UProperty = 39;
|
||||
pub static UCHAR_NFKC_INERT : UProperty = 40;
|
||||
pub static UCHAR_SEGMENT_STARTER : UProperty = 41;
|
||||
pub static UCHAR_PATTERN_SYNTAX : UProperty = 42;
|
||||
|
||||
pub static UCHAR_PATTERN_WHITE_SPACE : UProperty = 43;
|
||||
pub static UCHAR_POSIX_ALNUM : UProperty = 44;
|
||||
pub static UCHAR_POSIX_BLANK : UProperty = 45;
|
||||
pub static UCHAR_POSIX_GRAPH : UProperty = 46;
|
||||
|
||||
pub static UCHAR_POSIX_PRINT : UProperty = 47;
|
||||
pub static UCHAR_POSIX_XDIGIT : UProperty = 48;
|
||||
pub static UCHAR_CASED : UProperty = 49;
|
||||
pub static UCHAR_CASE_IGNORABLE : UProperty = 50;
|
||||
|
||||
pub static UCHAR_CHANGES_WHEN_LOWERCASED : UProperty = 51;
|
||||
pub static UCHAR_CHANGES_WHEN_UPPERCASED : UProperty = 52;
|
||||
pub static UCHAR_CHANGES_WHEN_TITLECASED : UProperty = 53;
|
||||
pub static UCHAR_CHANGES_WHEN_CASEFOLDED : UProperty = 54;
|
||||
|
||||
pub static UCHAR_CHANGES_WHEN_CASEMAPPED : UProperty = 55;
|
||||
pub static UCHAR_CHANGES_WHEN_NFKC_CASEFOLDED : UProperty = 56;
|
||||
pub static UCHAR_BINARY_LIMIT : UProperty = 57;
|
||||
pub static UCHAR_BIDI_CLASS : UProperty = 0x1000;
|
||||
|
||||
pub static UCHAR_INT_START : UProperty = 0x1000; // UCHAR_BIDI_CLASS
|
||||
pub static UCHAR_BLOCK : UProperty = 0x1001;
|
||||
pub static UCHAR_CANONICAL_COMBINING_CLASS : UProperty = 0x1002;
|
||||
pub static UCHAR_DECOMPOSITION_TYPE : UProperty = 0x1003;
|
||||
|
||||
pub static UCHAR_EAST_ASIAN_WIDTH : UProperty = 0x1004;
|
||||
pub static UCHAR_GENERAL_CATEGORY : UProperty = 0x1005;
|
||||
pub static UCHAR_JOINING_GROUP : UProperty = 0x1006;
|
||||
pub static UCHAR_JOINING_TYPE : UProperty = 0x1007;
|
||||
|
||||
pub static UCHAR_LINE_BREAK : UProperty = 0x1008;
|
||||
pub static UCHAR_NUMERIC_TYPE : UProperty = 0x1009;
|
||||
pub static UCHAR_SCRIPT : UProperty = 0x100A;
|
||||
pub static UCHAR_HANGUL_SYLLABLE_TYPE : UProperty = 0x100B;
|
||||
|
||||
pub static UCHAR_NFD_QUICK_CHECK : UProperty = 0x100C;
|
||||
pub static UCHAR_NFKD_QUICK_CHECK : UProperty = 0x100D;
|
||||
pub static UCHAR_NFC_QUICK_CHECK : UProperty = 0x100E;
|
||||
pub static UCHAR_NFKC_QUICK_CHECK : UProperty = 0x100F;
|
||||
|
||||
pub static UCHAR_LEAD_CANONICAL_COMBINING_CLASS : UProperty = 0x1010;
|
||||
pub static UCHAR_TRAIL_CANONICAL_COMBINING_CLASS : UProperty = 0x1011;
|
||||
pub static UCHAR_GRAPHEME_CLUSTER_BREAK : UProperty = 0x1012;
|
||||
pub static UCHAR_SENTENCE_BREAK : UProperty = 0x1013;
|
||||
|
||||
pub static UCHAR_WORD_BREAK : UProperty = 0x1014;
|
||||
pub static UCHAR_INT_LIMIT : UProperty = 0x1015;
|
||||
|
||||
pub static UCHAR_GENERAL_CATEGORY_MASK : UProperty = 0x2000;
|
||||
pub static UCHAR_MASK_START : UProperty = 0x2000;
|
||||
// = UCHAR_GENERAL_CATEGORY_MASK
|
||||
pub static UCHAR_MASK_LIMIT : UProperty = 0x2001;
|
||||
|
||||
pub static UCHAR_NUMERIC_VALUE : UProperty = 0x3000;
|
||||
pub static UCHAR_DOUBLE_START : UProperty = 0x3000;
|
||||
// = UCHAR_NUMERIC_VALUE
|
||||
pub static UCHAR_DOUBLE_LIMIT : UProperty = 0x3001;
|
||||
|
||||
pub static UCHAR_AGE : UProperty = 0x4000;
|
||||
pub static UCHAR_STRING_START : UProperty = 0x4000; // = UCHAR_AGE
|
||||
pub static UCHAR_BIDI_MIRRORING_GLYPH : UProperty = 0x4001;
|
||||
pub static UCHAR_CASE_FOLDING : UProperty = 0x4002;
|
||||
|
||||
pub static UCHAR_ISO_COMMENT : UProperty = 0x4003;
|
||||
pub static UCHAR_LOWERCASE_MAPPING : UProperty = 0x4004;
|
||||
pub static UCHAR_NAME : UProperty = 0x4005;
|
||||
pub static UCHAR_SIMPLE_CASE_FOLDING : UProperty = 0x4006;
|
||||
|
||||
pub static UCHAR_SIMPLE_LOWERCASE_MAPPING : UProperty = 0x4007;
|
||||
pub static UCHAR_SIMPLE_TITLECASE_MAPPING : UProperty = 0x4008;
|
||||
pub static UCHAR_SIMPLE_UPPERCASE_MAPPING : UProperty = 0x4009;
|
||||
pub static UCHAR_TITLECASE_MAPPING : UProperty = 0x400A;
|
||||
|
||||
pub static UCHAR_UNICODE_1_NAME : UProperty = 0x400B;
|
||||
pub static UCHAR_UPPERCASE_MAPPING : UProperty = 0x400C;
|
||||
pub static UCHAR_STRING_LIMIT : UProperty = 0x400D;
|
||||
|
||||
pub static UCHAR_SCRIPT_EXTENSIONS : UProperty = 0x7000;
|
||||
pub static UCHAR_OTHER_PROPERTY_START : UProperty = 0x7000;
|
||||
// = UCHAR_SCRIPT_EXTENSIONS;
|
||||
pub static UCHAR_OTHER_PROPERTY_LIMIT : UProperty = 0x7001;
|
||||
|
||||
pub static UCHAR_INVALID_CODE : UProperty = -1;
|
||||
|
||||
pub mod libicu {
|
||||
#[link_name = "icuuc"]
|
||||
#[abi = "cdecl"]
|
||||
pub extern {
|
||||
unsafe fn u_hasBinaryProperty(c: UChar32, which: UProperty)
|
||||
-> UBool;
|
||||
unsafe fn u_isdigit(c: UChar32) -> UBool;
|
||||
unsafe fn u_islower(c: UChar32) -> UBool;
|
||||
unsafe fn u_isspace(c: UChar32) -> UBool;
|
||||
unsafe fn u_isupper(c: UChar32) -> UBool;
|
||||
unsafe fn u_tolower(c: UChar32) -> UChar32;
|
||||
unsafe fn u_toupper(c: UChar32) -> UChar32;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_XID_start(c: char) -> bool {
|
||||
return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
|
||||
== icu::TRUE;
|
||||
}
|
||||
|
||||
pub fn is_XID_continue(c: char) -> bool {
|
||||
return icu::libicu::u_hasBinaryProperty(c, icu::UCHAR_XID_START)
|
||||
== icu::TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: is_digit
|
||||
|
||||
Returns true if a character is a digit.
|
||||
*/
|
||||
pub fn is_digit(c: char) -> bool {
|
||||
return icu::libicu::u_isdigit(c) == icu::TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: is_lower
|
||||
|
||||
Returns true if a character is a lowercase letter.
|
||||
*/
|
||||
pub fn is_lower(c: char) -> bool {
|
||||
return icu::libicu::u_islower(c) == icu::TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: is_space
|
||||
|
||||
Returns true if a character is space.
|
||||
*/
|
||||
pub fn is_space(c: char) -> bool {
|
||||
return icu::libicu::u_isspace(c) == icu::TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
Function: is_upper
|
||||
|
||||
Returns true if a character is an uppercase letter.
|
||||
*/
|
||||
pub fn is_upper(c: char) -> bool {
|
||||
return icu::libicu::u_isupper(c) == icu::TRUE;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_is_digit() {
|
||||
assert!((unicode::icu::is_digit('0')));
|
||||
assert!((!unicode::icu::is_digit('m')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_lower() {
|
||||
assert!((unicode::icu::is_lower('m')));
|
||||
assert!((!unicode::icu::is_lower('M')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_space() {
|
||||
assert!((unicode::icu::is_space(' ')));
|
||||
assert!((!unicode::icu::is_space('m')));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_upper() {
|
||||
assert!((unicode::icu::is_upper('M')));
|
||||
assert!((!unicode::icu::is_upper('m')));
|
||||
}
|
||||
}
|
@ -9,102 +9,802 @@
|
||||
// except according to those terms.
|
||||
|
||||
/*!
|
||||
|
||||
Higher level communication abstractions.
|
||||
|
||||
Message passing
|
||||
*/
|
||||
|
||||
use core::comm::{GenericChan, GenericSmartChan, GenericPort};
|
||||
use core::comm::{Chan, Port, Selectable, Peekable};
|
||||
use core::pipes;
|
||||
use cast::{transmute, transmute_mut};
|
||||
use container::Container;
|
||||
use either::{Either, Left, Right};
|
||||
use kinds::Owned;
|
||||
use option::{Option, Some, None};
|
||||
use uint;
|
||||
use vec;
|
||||
use vec::OwnedVector;
|
||||
use util::replace;
|
||||
use unstable::sync::{Exclusive, exclusive};
|
||||
use rtcomm = rt::comm;
|
||||
use rt;
|
||||
|
||||
/// An extension of `pipes::stream` that allows both sending and receiving.
|
||||
pub struct DuplexStream<T, U> {
|
||||
priv chan: Chan<T>,
|
||||
priv port: Port<U>,
|
||||
use pipes::{wait_many, PacketHeader};
|
||||
|
||||
// FIXME #5160: Making this public exposes some plumbing from
|
||||
// pipes. Needs some refactoring
|
||||
pub use pipes::Selectable;
|
||||
|
||||
/// A trait for things that can send multiple messages.
|
||||
pub trait GenericChan<T> {
|
||||
/// Sends a message.
|
||||
fn send(&self, x: T);
|
||||
}
|
||||
|
||||
// Allow these methods to be used without import:
|
||||
pub impl<T:Owned,U:Owned> DuplexStream<T, U> {
|
||||
/// Things that can send multiple messages and can detect when the receiver
|
||||
/// is closed
|
||||
pub trait GenericSmartChan<T> {
|
||||
/// Sends a message, or report if the receiver has closed the connection.
|
||||
fn try_send(&self, x: T) -> bool;
|
||||
}
|
||||
|
||||
/// A trait for things that can receive multiple messages.
|
||||
pub trait GenericPort<T> {
|
||||
/// Receives a message, or fails if the connection closes.
|
||||
fn recv(&self) -> T;
|
||||
|
||||
/** Receives a message, or returns `none` if
|
||||
the connection is closed or closes.
|
||||
*/
|
||||
fn try_recv(&self) -> Option<T>;
|
||||
}
|
||||
|
||||
/// Ports that can `peek`
|
||||
pub trait Peekable<T> {
|
||||
/// Returns true if a message is available
|
||||
fn peek(&self) -> bool;
|
||||
}
|
||||
|
||||
/// An endpoint that can send many messages.
|
||||
pub struct Chan<T> {
|
||||
inner: Either<pipesy::Chan<T>, rtcomm::Chan<T>>
|
||||
}
|
||||
|
||||
/// An endpoint that can receive many messages.
|
||||
pub struct Port<T> {
|
||||
inner: Either<pipesy::Port<T>, rtcomm::Port<T>>
|
||||
}
|
||||
|
||||
/** Creates a `(Port, Chan)` pair.
|
||||
|
||||
These allow sending or receiving an unlimited number of messages.
|
||||
|
||||
*/
|
||||
pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
|
||||
let (port, chan) = match rt::context() {
|
||||
rt::OldTaskContext => match pipesy::stream() {
|
||||
(p, c) => (Left(p), Left(c))
|
||||
},
|
||||
_ => match rtcomm::stream() {
|
||||
(p, c) => (Right(p), Right(c))
|
||||
}
|
||||
};
|
||||
let port = Port { inner: port };
|
||||
let chan = Chan { inner: chan };
|
||||
return (port, chan);
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for Chan<T> {
|
||||
fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
}
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
self.chan.try_send(x)
|
||||
}
|
||||
fn recv(&self, ) -> U {
|
||||
self.port.recv()
|
||||
}
|
||||
fn try_recv(&self) -> Option<U> {
|
||||
self.port.try_recv()
|
||||
}
|
||||
fn peek(&self) -> bool {
|
||||
self.port.peek()
|
||||
match self.inner {
|
||||
Left(ref chan) => chan.send(x),
|
||||
Right(ref chan) => chan.send(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericChan<T> for DuplexStream<T, U> {
|
||||
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
match self.inner {
|
||||
Left(ref chan) => chan.try_send(x),
|
||||
Right(ref chan) => chan.try_send(x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericPort<T> for Port<T> {
|
||||
fn recv(&self) -> T {
|
||||
match self.inner {
|
||||
Left(ref port) => port.recv(),
|
||||
Right(ref port) => port.recv()
|
||||
}
|
||||
}
|
||||
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
match self.inner {
|
||||
Left(ref port) => port.try_recv(),
|
||||
Right(ref port) => port.try_recv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for Port<T> {
|
||||
fn peek(&self) -> bool {
|
||||
match self.inner {
|
||||
Left(ref port) => port.peek(),
|
||||
Right(ref port) => port.peek()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Selectable for Port<T> {
|
||||
fn header(&mut self) -> *mut PacketHeader {
|
||||
match self.inner {
|
||||
Left(ref mut port) => port.header(),
|
||||
Right(_) => fail!("can't select on newsched ports")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Treat many ports as one.
|
||||
#[unsafe_mut_field(ports)]
|
||||
pub struct PortSet<T> {
|
||||
ports: ~[pipesy::Port<T>],
|
||||
}
|
||||
|
||||
pub impl<T: Owned> PortSet<T> {
|
||||
fn new() -> PortSet<T> {
|
||||
PortSet {
|
||||
ports: ~[]
|
||||
}
|
||||
}
|
||||
|
||||
fn add(&self, port: Port<T>) {
|
||||
let Port { inner } = port;
|
||||
let port = match inner {
|
||||
Left(p) => p,
|
||||
Right(_) => fail!("PortSet not implemented")
|
||||
};
|
||||
unsafe {
|
||||
let self_ports = transmute_mut(&self.ports);
|
||||
self_ports.push(port)
|
||||
}
|
||||
}
|
||||
|
||||
fn chan(&self) -> Chan<T> {
|
||||
let (po, ch) = stream();
|
||||
self.add(po);
|
||||
ch
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned> GenericPort<T> for PortSet<T> {
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
unsafe {
|
||||
let self_ports = transmute_mut(&self.ports);
|
||||
let mut result = None;
|
||||
// we have to swap the ports array so we aren't borrowing
|
||||
// aliasable mutable memory.
|
||||
let mut ports = replace(self_ports, ~[]);
|
||||
while result.is_none() && ports.len() > 0 {
|
||||
let i = wait_many(ports);
|
||||
match ports[i].try_recv() {
|
||||
Some(m) => {
|
||||
result = Some(m);
|
||||
}
|
||||
None => {
|
||||
// Remove this port.
|
||||
let _ = ports.swap_remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
*self_ports = ports;
|
||||
result
|
||||
}
|
||||
}
|
||||
fn recv(&self) -> T {
|
||||
self.try_recv().expect("port_set: endpoints closed")
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for PortSet<T> {
|
||||
fn peek(&self) -> bool {
|
||||
// It'd be nice to use self.port.each, but that version isn't
|
||||
// pure.
|
||||
for uint::range(0, vec::uniq_len(&const self.ports)) |i| {
|
||||
let port: &pipesy::Port<T> = &self.ports[i];
|
||||
if port.peek() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
/// A channel that can be shared between many senders.
|
||||
pub struct SharedChan<T> {
|
||||
ch: Exclusive<pipesy::Chan<T>>
|
||||
}
|
||||
|
||||
impl<T: Owned> SharedChan<T> {
|
||||
/// Converts a `chan` into a `shared_chan`.
|
||||
pub fn new(c: Chan<T>) -> SharedChan<T> {
|
||||
let Chan { inner } = c;
|
||||
let c = match inner {
|
||||
Left(c) => c,
|
||||
Right(_) => fail!("SharedChan not implemented")
|
||||
};
|
||||
SharedChan { ch: exclusive(c) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for SharedChan<T> {
|
||||
fn send(&self, x: T) {
|
||||
self.chan.send(x)
|
||||
let mut xx = Some(x);
|
||||
do self.ch.with_imm |chan| {
|
||||
let x = replace(&mut xx, None);
|
||||
chan.send(x.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericSmartChan<T> for DuplexStream<T, U> {
|
||||
impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
self.chan.try_send(x)
|
||||
let mut xx = Some(x);
|
||||
do self.ch.with_imm |chan| {
|
||||
let x = replace(&mut xx, None);
|
||||
chan.try_send(x.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> GenericPort<U> for DuplexStream<T, U> {
|
||||
fn recv(&self) -> U {
|
||||
self.port.recv()
|
||||
}
|
||||
|
||||
fn try_recv(&self) -> Option<U> {
|
||||
self.port.try_recv()
|
||||
impl<T: Owned> ::clone::Clone for SharedChan<T> {
|
||||
fn clone(&self) -> SharedChan<T> {
|
||||
SharedChan { ch: self.ch.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Peekable<U> for DuplexStream<T, U> {
|
||||
fn peek(&self) -> bool {
|
||||
self.port.peek()
|
||||
pub struct PortOne<T> {
|
||||
inner: Either<pipesy::PortOne<T>, rtcomm::PortOne<T>>
|
||||
}
|
||||
|
||||
pub struct ChanOne<T> {
|
||||
inner: Either<pipesy::ChanOne<T>, rtcomm::ChanOne<T>>
|
||||
}
|
||||
|
||||
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
|
||||
let (port, chan) = match rt::context() {
|
||||
rt::OldTaskContext => match pipesy::oneshot() {
|
||||
(p, c) => (Left(p), Left(c)),
|
||||
},
|
||||
_ => match rtcomm::oneshot() {
|
||||
(p, c) => (Right(p), Right(c))
|
||||
}
|
||||
};
|
||||
let port = PortOne { inner: port };
|
||||
let chan = ChanOne { inner: chan };
|
||||
return (port, chan);
|
||||
}
|
||||
|
||||
impl<T: Owned> PortOne<T> {
|
||||
pub fn recv(self) -> T {
|
||||
let PortOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.recv(),
|
||||
Right(p) => p.recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_recv(self) -> Option<T> {
|
||||
let PortOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.try_recv(),
|
||||
Right(p) => p.try_recv()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:Owned,U:Owned> Selectable for DuplexStream<T, U> {
|
||||
fn header(&mut self) -> *mut pipes::PacketHeader {
|
||||
self.port.header()
|
||||
impl<T: Owned> ChanOne<T> {
|
||||
pub fn send(self, data: T) {
|
||||
let ChanOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.send(data),
|
||||
Right(p) => p.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_send(self, data: T) -> bool {
|
||||
let ChanOne { inner } = self;
|
||||
match inner {
|
||||
Left(p) => p.try_send(data),
|
||||
Right(p) => p.try_send(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a bidirectional stream.
|
||||
pub fn DuplexStream<T:Owned,U:Owned>()
|
||||
-> (DuplexStream<T, U>, DuplexStream<U, T>)
|
||||
{
|
||||
let (p1, c2) = comm::stream();
|
||||
let (p2, c1) = comm::stream();
|
||||
(DuplexStream {
|
||||
chan: c1,
|
||||
port: p1
|
||||
},
|
||||
DuplexStream {
|
||||
chan: c2,
|
||||
port: p2
|
||||
})
|
||||
pub fn recv_one<T: Owned>(port: PortOne<T>) -> T {
|
||||
let PortOne { inner } = port;
|
||||
match inner {
|
||||
Left(p) => pipesy::recv_one(p),
|
||||
Right(p) => p.recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_recv_one<T: Owned>(port: PortOne<T>) -> Option<T> {
|
||||
let PortOne { inner } = port;
|
||||
match inner {
|
||||
Left(p) => pipesy::try_recv_one(p),
|
||||
Right(p) => p.try_recv()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) {
|
||||
let ChanOne { inner } = chan;
|
||||
match inner {
|
||||
Left(c) => pipesy::send_one(c, data),
|
||||
Right(c) => c.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
|
||||
let ChanOne { inner } = chan;
|
||||
match inner {
|
||||
Left(c) => pipesy::try_send_one(c, data),
|
||||
Right(c) => c.try_send(data)
|
||||
}
|
||||
}
|
||||
|
||||
mod pipesy {
|
||||
|
||||
use kinds::Owned;
|
||||
use option::{Option, Some, None};
|
||||
use pipes::{recv, try_recv, peek, PacketHeader};
|
||||
use super::{GenericChan, GenericSmartChan, GenericPort, Peekable, Selectable};
|
||||
use cast::transmute_mut;
|
||||
use util::replace;
|
||||
|
||||
/*proto! oneshot (
|
||||
Oneshot:send<T:Owned> {
|
||||
send(T) -> !
|
||||
}
|
||||
)*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod oneshot {
|
||||
priv use core::kinds::Owned;
|
||||
use ptr::to_mut_unsafe_ptr;
|
||||
|
||||
pub fn init<T: Owned>() -> (client::Oneshot<T>, server::Oneshot<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
|
||||
let buffer = ~::core::pipes::Buffer {
|
||||
header: ::core::pipes::BufferHeader(),
|
||||
data: __Buffer {
|
||||
Oneshot: ::core::pipes::mk_packet::<Oneshot<T>>()
|
||||
},
|
||||
};
|
||||
do ::core::pipes::entangle_buffer(buffer) |buffer, data| {
|
||||
data.Oneshot.set_buffer(buffer);
|
||||
to_mut_unsafe_ptr(&mut data.Oneshot)
|
||||
}
|
||||
}
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Oneshot<T> { pub send(T), }
|
||||
#[allow(non_camel_case_types)]
|
||||
pub struct __Buffer<T> {
|
||||
Oneshot: ::core::pipes::Packet<Oneshot<T>>,
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_send<T: Owned>(pipe: Oneshot<T>, x_0: T) ->
|
||||
::core::option::Option<()> {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(())
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn send<T: Owned>(pipe: Oneshot<T>, x_0: T) {
|
||||
{
|
||||
use super::send;
|
||||
let message = send(x_0);
|
||||
::core::pipes::send(pipe, message);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::SendPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Oneshot<T> =
|
||||
::core::pipes::RecvPacketBuffered<super::Oneshot<T>,
|
||||
super::__Buffer<T>>;
|
||||
}
|
||||
}
|
||||
|
||||
/// The send end of a oneshot pipe.
|
||||
pub struct ChanOne<T> {
|
||||
contents: oneshot::client::Oneshot<T>
|
||||
}
|
||||
|
||||
impl<T> ChanOne<T> {
|
||||
pub fn new(contents: oneshot::client::Oneshot<T>) -> ChanOne<T> {
|
||||
ChanOne {
|
||||
contents: contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The receive end of a oneshot pipe.
|
||||
pub struct PortOne<T> {
|
||||
contents: oneshot::server::Oneshot<T>
|
||||
}
|
||||
|
||||
impl<T> PortOne<T> {
|
||||
pub fn new(contents: oneshot::server::Oneshot<T>) -> PortOne<T> {
|
||||
PortOne {
|
||||
contents: contents
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialiase a (send-endpoint, recv-endpoint) oneshot pipe pair.
|
||||
pub fn oneshot<T: Owned>() -> (PortOne<T>, ChanOne<T>) {
|
||||
let (chan, port) = oneshot::init();
|
||||
(PortOne::new(port), ChanOne::new(chan))
|
||||
}
|
||||
|
||||
pub impl<T: Owned> PortOne<T> {
|
||||
fn recv(self) -> T { recv_one(self) }
|
||||
fn try_recv(self) -> Option<T> { try_recv_one(self) }
|
||||
fn unwrap(self) -> oneshot::server::Oneshot<T> {
|
||||
match self {
|
||||
PortOne { contents: s } => s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub impl<T: Owned> ChanOne<T> {
|
||||
fn send(self, data: T) { send_one(self, data) }
|
||||
fn try_send(self, data: T) -> bool { try_send_one(self, data) }
|
||||
fn unwrap(self) -> oneshot::client::Oneshot<T> {
|
||||
match self {
|
||||
ChanOne { contents: s } => s
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receive a message from a oneshot pipe, failing if the connection was
|
||||
* closed.
|
||||
*/
|
||||
pub fn recv_one<T: Owned>(port: PortOne<T>) -> T {
|
||||
match port {
|
||||
PortOne { contents: port } => {
|
||||
let oneshot::send(message) = recv(port);
|
||||
message
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a message from a oneshot pipe unless the connection was closed.
|
||||
pub fn try_recv_one<T: Owned> (port: PortOne<T>) -> Option<T> {
|
||||
match port {
|
||||
PortOne { contents: port } => {
|
||||
let message = try_recv(port);
|
||||
|
||||
if message.is_none() {
|
||||
None
|
||||
} else {
|
||||
let oneshot::send(message) = message.unwrap();
|
||||
Some(message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Send a message on a oneshot pipe, failing if the connection was closed.
|
||||
pub fn send_one<T: Owned>(chan: ChanOne<T>, data: T) {
|
||||
match chan {
|
||||
ChanOne { contents: chan } => oneshot::client::send(chan, data),
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a message on a oneshot pipe, or return false if the connection was
|
||||
* closed.
|
||||
*/
|
||||
pub fn try_send_one<T: Owned>(chan: ChanOne<T>, data: T) -> bool {
|
||||
match chan {
|
||||
ChanOne { contents: chan } => {
|
||||
oneshot::client::try_send(chan, data).is_some()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Streams - Make pipes a little easier in general.
|
||||
|
||||
/*proto! streamp (
|
||||
Open:send<T: Owned> {
|
||||
data(T) -> Open<T>
|
||||
}
|
||||
)*/
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod streamp {
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
pub fn init<T: Owned>() -> (client::Open<T>, server::Open<T>) {
|
||||
pub use core::pipes::HasBuffer;
|
||||
::core::pipes::entangle()
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub enum Open<T> { pub data(T, server::Open<T>), }
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod client {
|
||||
priv use core::kinds::Owned;
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn try_data<T: Owned>(pipe: Open<T>, x_0: T) ->
|
||||
::core::option::Option<Open<T>> {
|
||||
{
|
||||
use super::data;
|
||||
let (c, s) = ::core::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
if ::core::pipes::send(pipe, message) {
|
||||
::core::pipes::rt::make_some(c)
|
||||
} else { ::core::pipes::rt::make_none() }
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub fn data<T: Owned>(pipe: Open<T>, x_0: T) -> Open<T> {
|
||||
{
|
||||
use super::data;
|
||||
let (c, s) = ::core::pipes::entangle();
|
||||
let message = data(x_0, s);
|
||||
::core::pipes::send(pipe, message);
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::SendPacket<super::Open<T>>;
|
||||
}
|
||||
|
||||
#[allow(non_camel_case_types)]
|
||||
pub mod server {
|
||||
#[allow(non_camel_case_types)]
|
||||
pub type Open<T> = ::core::pipes::RecvPacket<super::Open<T>>;
|
||||
}
|
||||
}
|
||||
|
||||
/// An endpoint that can send many messages.
|
||||
#[unsafe_mut_field(endp)]
|
||||
pub struct Chan<T> {
|
||||
endp: Option<streamp::client::Open<T>>
|
||||
}
|
||||
|
||||
/// An endpoint that can receive many messages.
|
||||
#[unsafe_mut_field(endp)]
|
||||
pub struct Port<T> {
|
||||
endp: Option<streamp::server::Open<T>>,
|
||||
}
|
||||
|
||||
/** Creates a `(Port, Chan)` pair.
|
||||
|
||||
These allow sending or receiving an unlimited number of messages.
|
||||
|
||||
*/
|
||||
pub fn stream<T:Owned>() -> (Port<T>, Chan<T>) {
|
||||
let (c, s) = streamp::init();
|
||||
|
||||
(Port {
|
||||
endp: Some(s)
|
||||
}, Chan {
|
||||
endp: Some(c)
|
||||
})
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericChan<T> for Chan<T> {
|
||||
#[inline(always)]
|
||||
fn send(&self, x: T) {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
*self_endp = Some(streamp::client::data(endp.unwrap(), x))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericSmartChan<T> for Chan<T> {
|
||||
#[inline(always)]
|
||||
fn try_send(&self, x: T) -> bool {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
match streamp::client::try_data(endp.unwrap(), x) {
|
||||
Some(next) => {
|
||||
*self_endp = Some(next);
|
||||
true
|
||||
}
|
||||
None => false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> GenericPort<T> for Port<T> {
|
||||
#[inline(always)]
|
||||
fn recv(&self) -> T {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
let streamp::data(x, endp) = recv(endp.unwrap());
|
||||
*self_endp = Some(endp);
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn try_recv(&self) -> Option<T> {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let endp = replace(self_endp, None);
|
||||
match try_recv(endp.unwrap()) {
|
||||
Some(streamp::data(x, endp)) => {
|
||||
*self_endp = Some(endp);
|
||||
Some(x)
|
||||
}
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Peekable<T> for Port<T> {
|
||||
#[inline(always)]
|
||||
fn peek(&self) -> bool {
|
||||
unsafe {
|
||||
let self_endp = transmute_mut(&self.endp);
|
||||
let mut endp = replace(self_endp, None);
|
||||
let peek = match endp {
|
||||
Some(ref mut endp) => peek(endp),
|
||||
None => fail!("peeking empty stream")
|
||||
};
|
||||
*self_endp = endp;
|
||||
peek
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Owned> Selectable for Port<T> {
|
||||
fn header(&mut self) -> *mut PacketHeader {
|
||||
match self.endp {
|
||||
Some(ref mut endp) => endp.header(),
|
||||
None => fail!("peeking empty stream")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// Returns the index of an endpoint that is ready to receive.
|
||||
pub fn selecti<T: Selectable>(endpoints: &mut [T]) -> uint {
|
||||
wait_many(endpoints)
|
||||
}
|
||||
|
||||
/// Returns 0 or 1 depending on which endpoint is ready to receive
|
||||
pub fn select2i<A:Selectable, B:Selectable>(a: &mut A, b: &mut B)
|
||||
-> Either<(), ()> {
|
||||
let mut endpoints = [ a.header(), b.header() ];
|
||||
match wait_many(endpoints) {
|
||||
0 => Left(()),
|
||||
1 => Right(()),
|
||||
_ => fail!("wait returned unexpected index"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive a message from one of two endpoints.
|
||||
pub trait Select2<T: Owned, U: Owned> {
|
||||
/// Receive a message or return `None` if a connection closes.
|
||||
fn try_select(&mut self) -> Either<Option<T>, Option<U>>;
|
||||
/// Receive a message or fail if a connection closes.
|
||||
fn select(&mut self) -> Either<T, U>;
|
||||
}
|
||||
|
||||
impl<T:Owned,
|
||||
U:Owned,
|
||||
Left:Selectable + GenericPort<T>,
|
||||
Right:Selectable + GenericPort<U>>
|
||||
Select2<T, U>
|
||||
for (Left, Right) {
|
||||
fn select(&mut self) -> Either<T, U> {
|
||||
// XXX: Bad borrow check workaround.
|
||||
unsafe {
|
||||
let this: &(Left, Right) = transmute(self);
|
||||
match *this {
|
||||
(ref lp, ref rp) => {
|
||||
let lp: &mut Left = transmute(lp);
|
||||
let rp: &mut Right = transmute(rp);
|
||||
match select2i(lp, rp) {
|
||||
Left(()) => Left(lp.recv()),
|
||||
Right(()) => Right(rp.recv()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn try_select(&mut self) -> Either<Option<T>, Option<U>> {
|
||||
// XXX: Bad borrow check workaround.
|
||||
unsafe {
|
||||
let this: &(Left, Right) = transmute(self);
|
||||
match *this {
|
||||
(ref lp, ref rp) => {
|
||||
let lp: &mut Left = transmute(lp);
|
||||
let rp: &mut Right = transmute(rp);
|
||||
match select2i(lp, rp) {
|
||||
Left(()) => Left (lp.try_recv()),
|
||||
Right(()) => Right(rp.try_recv()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use comm::DuplexStream;
|
||||
use either::Right;
|
||||
use super::{Chan, Port, oneshot, stream};
|
||||
|
||||
#[test]
|
||||
pub fn DuplexStream1() {
|
||||
let (left, right) = DuplexStream();
|
||||
fn test_select2() {
|
||||
let (p1, c1) = stream();
|
||||
let (p2, c2) = stream();
|
||||
|
||||
left.send(~"abc");
|
||||
right.send(123);
|
||||
c1.send(~"abc");
|
||||
|
||||
assert_eq!(left.recv(), 123);
|
||||
assert_eq!(right.recv(), ~"abc");
|
||||
let mut tuple = (p1, p2);
|
||||
match tuple.select() {
|
||||
Right(_) => fail!(),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
c2.send(123);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_oneshot() {
|
||||
let (p, c) = oneshot();
|
||||
|
||||
c.send(());
|
||||
|
||||
p.recv()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peek_terminated() {
|
||||
let (port, chan): (Port<int>, Chan<int>) = stream();
|
||||
|
||||
{
|
||||
// Destroy the channel
|
||||
let _chan = chan;
|
||||
}
|
||||
|
||||
assert!(!port.peek());
|
||||
}
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user