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:
Patrick Walton 2013-05-17 10:45:09 -07:00
parent 565942b145
commit 0c820d4123
186 changed files with 4015 additions and 4059 deletions

View File

@ -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
View File

@ -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

View File

@ -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))

View File

@ -33,9 +33,9 @@ PKG_FILES := \
compiletest \
etc \
libfuzzer \
libcore \
libsyntax \
libextra \
libstd \
libsyntax \
rt \
librustdoc \
rustllvm \

View File

@ -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

View File

@ -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: $$@)

View File

@ -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)))

View File

@ -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) \

View File

@ -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: $$@)

View File

@ -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 $$@

View File

@ -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

View File

@ -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)) \

View File

@ -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
View 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
View 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')));
}
}

View File

@ -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