mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-30 04:17:31 +09:00
parent
5983fef8c5
commit
963560a1d2
496 changed files with 4 additions and 788702 deletions
|
|
@ -1,166 +0,0 @@
|
||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
option('--enable-rust', help='Include Rust language sources')
|
|
||||||
|
|
||||||
@depends('--enable-rust')
|
|
||||||
def rust_compiler_names(value):
|
|
||||||
if value:
|
|
||||||
return ['rustc']
|
|
||||||
|
|
||||||
@depends('--enable-rust')
|
|
||||||
def cargo_binary_names(value):
|
|
||||||
if value:
|
|
||||||
return ['cargo']
|
|
||||||
|
|
||||||
rustc = check_prog('RUSTC', rust_compiler_names, allow_missing=True)
|
|
||||||
cargo = check_prog('CARGO', cargo_binary_names, allow_missing=True)
|
|
||||||
|
|
||||||
@depends_if(rustc)
|
|
||||||
@checking('rustc version', lambda info: info.version)
|
|
||||||
def rustc_info(rustc):
|
|
||||||
out = check_cmd_output(rustc, '--version', '--verbose').splitlines()
|
|
||||||
info = dict((s.strip() for s in line.split(':', 1)) for line in out[1:])
|
|
||||||
return namespace(
|
|
||||||
version=Version(info.get('release', '0')),
|
|
||||||
commit=info.get('commit-hash', 'unknown'),
|
|
||||||
)
|
|
||||||
|
|
||||||
@depends_if(cargo)
|
|
||||||
@checking('cargo support for --frozen')
|
|
||||||
@imports('subprocess')
|
|
||||||
@imports('os')
|
|
||||||
def cargo_supports_frozen(cargo):
|
|
||||||
try:
|
|
||||||
lines = subprocess.check_output(
|
|
||||||
[cargo, 'help', 'build']
|
|
||||||
).splitlines()
|
|
||||||
supported = any(' --frozen' in l for l in lines)
|
|
||||||
if 'MOZ_AUTOMATION' in os.environ and not supported:
|
|
||||||
die('cargo in automation must support --frozen')
|
|
||||||
return supported
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
die('Failed to call cargo: %s', e.message)
|
|
||||||
|
|
||||||
set_config('MOZ_CARGO_SUPPORTS_FROZEN', cargo_supports_frozen)
|
|
||||||
|
|
||||||
@depends('--enable-rust', rustc, rustc_info)
|
|
||||||
@imports(_from='textwrap', _import='dedent')
|
|
||||||
def rust_compiler(value, rustc, rustc_info):
|
|
||||||
if value:
|
|
||||||
if not rustc:
|
|
||||||
die(dedent('''\
|
|
||||||
Rust compiler not found.
|
|
||||||
To compile rust language sources, you must have 'rustc' in your path.
|
|
||||||
See https//www.rust-lang.org/ for more information.
|
|
||||||
'''))
|
|
||||||
version = rustc_info.version
|
|
||||||
min_version = Version('1.10')
|
|
||||||
if version < min_version:
|
|
||||||
die(dedent('''\
|
|
||||||
Rust compiler {} is too old.
|
|
||||||
To compile Rust language sources please install at least
|
|
||||||
version {} of the 'rustc' toolchain and make sure it is
|
|
||||||
first in your path.
|
|
||||||
You can verify this by typing 'rustc --version'.
|
|
||||||
'''.format(version, min_version)))
|
|
||||||
return True
|
|
||||||
|
|
||||||
set_config('MOZ_RUST', rust_compiler)
|
|
||||||
|
|
||||||
@depends(rust_compiler, rustc, target, cross_compiling)
|
|
||||||
@imports('os')
|
|
||||||
@imports('subprocess')
|
|
||||||
@imports(_from='mozbuild.configure.util', _import='LineIO')
|
|
||||||
@imports(_from='mozbuild.shellutil', _import='quote')
|
|
||||||
@imports(_from='tempfile', _import='mkstemp')
|
|
||||||
def rust_target(rust_compiler, rustc, target, cross_compiling):
|
|
||||||
if rust_compiler:
|
|
||||||
# Rust's --target options are similar to, but not exactly the same
|
|
||||||
# as, the autoconf-derived targets we use. An example would be that
|
|
||||||
# Rust uses distinct target triples for targetting the GNU C++ ABI
|
|
||||||
# and the MSVC C++ ABI on Win32, whereas autoconf has a single
|
|
||||||
# triple and relies on the user to ensure that everything is
|
|
||||||
# compiled for the appropriate ABI. We need to perform appropriate
|
|
||||||
# munging to get the correct option to rustc.
|
|
||||||
#
|
|
||||||
# The canonical list of targets supported can be derived from:
|
|
||||||
#
|
|
||||||
# https://github.com/rust-lang/rust/tree/master/mk/cfg
|
|
||||||
|
|
||||||
# Avoid having to write out os+kernel for all the platforms where
|
|
||||||
# they don't differ.
|
|
||||||
os_or_kernel = target.kernel if target.kernel == 'Linux' and target.os != 'Android' else target.os
|
|
||||||
rustc_target = {
|
|
||||||
# DragonFly
|
|
||||||
('x86_64', 'DragonFly'): 'x86_64-unknown-dragonfly',
|
|
||||||
# FreeBSD
|
|
||||||
('x86', 'FreeBSD'): 'i686-unknown-freebsd',
|
|
||||||
('x86_64', 'FreeBSD'): 'x86_64-unknown-freebsd',
|
|
||||||
# NetBSD
|
|
||||||
('x86_64', 'NetBSD'): 'x86_64-unknown-netbsd',
|
|
||||||
# OpenBSD
|
|
||||||
('x86_64', 'OpenBSD'): 'x86_64-unknown-openbsd',
|
|
||||||
# Linux
|
|
||||||
('x86', 'Linux'): 'i586-unknown-linux-gnu',
|
|
||||||
# Linux
|
|
||||||
('x86_64', 'Linux'): 'x86_64-unknown-linux-gnu',
|
|
||||||
# OS X and iOS
|
|
||||||
('x86', 'OSX'): 'i686-apple-darwin',
|
|
||||||
('x86', 'iOS'): 'i386-apple-ios',
|
|
||||||
('x86_64', 'OSX'): 'x86_64-apple-darwin',
|
|
||||||
# Android
|
|
||||||
('x86', 'Android'): 'i686-linux-android',
|
|
||||||
('arm', 'Android'): 'armv7-linux-androideabi',
|
|
||||||
# Windows
|
|
||||||
# XXX better detection of CXX needed here, to figure out whether
|
|
||||||
# we need i686-pc-windows-gnu instead, since mingw32 builds work.
|
|
||||||
('x86', 'WINNT'): 'i686-pc-windows-msvc',
|
|
||||||
('x86_64', 'WINNT'): 'x86_64-pc-windows-msvc',
|
|
||||||
}.get((target.cpu, os_or_kernel), None)
|
|
||||||
|
|
||||||
if rustc_target is None:
|
|
||||||
die("Don't know how to translate {} for rustc".format(target.alias))
|
|
||||||
|
|
||||||
# Check to see whether our rustc has a reasonably functional stdlib
|
|
||||||
# for our chosen target.
|
|
||||||
target_arg = '--target=' + rustc_target
|
|
||||||
in_fd, in_path = mkstemp(prefix='conftest', suffix='.rs')
|
|
||||||
out_fd, out_path = mkstemp(prefix='conftest', suffix='.rlib')
|
|
||||||
os.close(out_fd)
|
|
||||||
try:
|
|
||||||
source = 'pub extern fn hello() { println!("Hello world"); }'
|
|
||||||
log.debug('Creating `%s` with content:', in_path)
|
|
||||||
with LineIO(lambda l: log.debug('| %s', l)) as out:
|
|
||||||
out.write(source)
|
|
||||||
|
|
||||||
os.write(in_fd, source)
|
|
||||||
os.close(in_fd)
|
|
||||||
|
|
||||||
cmd = [
|
|
||||||
rustc,
|
|
||||||
'--crate-type', 'staticlib',
|
|
||||||
target_arg,
|
|
||||||
'-o', out_path,
|
|
||||||
in_path,
|
|
||||||
]
|
|
||||||
def failed():
|
|
||||||
die('Cannot compile for {} with {}'.format(target.alias, rustc))
|
|
||||||
check_cmd_output(*cmd, onerror=failed)
|
|
||||||
if not os.path.exists(out_path) or os.path.getsize(out_path) == 0:
|
|
||||||
failed()
|
|
||||||
finally:
|
|
||||||
os.remove(in_path)
|
|
||||||
os.remove(out_path)
|
|
||||||
# This target is usable.
|
|
||||||
return rustc_target
|
|
||||||
|
|
||||||
set_config('RUST_TARGET', rust_target)
|
|
||||||
|
|
||||||
# Until we remove all the other Rust checks in old-configure.
|
|
||||||
add_old_configure_assignment('MOZ_RUST', rust_compiler)
|
|
||||||
add_old_configure_assignment('RUSTC', rustc)
|
|
||||||
add_old_configure_assignment('RUST_TARGET', rust_target)
|
|
||||||
|
|
@ -907,4 +907,3 @@ set_config('WRAP_SYSTEM_INCLUDES', wrap_system_includes)
|
||||||
set_config('VISIBILITY_FLAGS', visibility_flags)
|
set_config('VISIBILITY_FLAGS', visibility_flags)
|
||||||
|
|
||||||
include('windows.configure')
|
include('windows.configure')
|
||||||
include('rust.configure')
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
# Options to enable rust in automation builds.
|
|
||||||
|
|
||||||
# Tell configure to use the tooltool rustc.
|
|
||||||
# Assume this is compiled with --enable-rpath so we don't
|
|
||||||
# have to set LD_LIBRARY_PATH.
|
|
||||||
RUSTC="$topsrcdir/rustc/bin/rustc"
|
|
||||||
CARGO="$topsrcdir/cargo/bin/cargo"
|
|
||||||
|
|
||||||
# Enable rust in the build.
|
|
||||||
ac_add_options --enable-rust
|
|
||||||
|
|
@ -60,14 +60,6 @@ def Library(name):
|
||||||
LIBRARY_NAME = name
|
LIBRARY_NAME = name
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
@template
|
||||||
def SharedLibrary(name):
|
def SharedLibrary(name):
|
||||||
'''Template for shared libraries.'''
|
'''Template for shared libraries.'''
|
||||||
|
|
|
||||||
|
|
@ -905,44 +905,6 @@ $(ASOBJS):
|
||||||
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef MOZ_RUST
|
|
||||||
ifdef RUST_LIBRARY_FILE
|
|
||||||
|
|
||||||
# Permit users to pass flags to cargo from their mozconfigs (e.g. --color=always).
|
|
||||||
cargo_build_flags = $(CARGOFLAGS)
|
|
||||||
ifndef MOZ_DEBUG
|
|
||||||
cargo_build_flags = --release
|
|
||||||
endif
|
|
||||||
ifdef MOZ_CARGO_SUPPORTS_FROZEN
|
|
||||||
cargo_build_flags += --frozen
|
|
||||||
endif
|
|
||||||
|
|
||||||
cargo_build_flags += --manifest-path $(CARGO_FILE)
|
|
||||||
cargo_build_flags += --target=$(RUST_TARGET)
|
|
||||||
cargo_build_flags += --verbose
|
|
||||||
|
|
||||||
# Enable color output if original stdout was a TTY and color settings
|
|
||||||
# aren't already present. This essentially restores the default behavior
|
|
||||||
# of cargo when running via `mach`.
|
|
||||||
ifdef MACH_STDOUT_ISATTY
|
|
||||||
ifeq (,$(findstring --color,$(cargo_build_flags)))
|
|
||||||
cargo_build_flags += --color=always
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Assume any system libraries rustc links against are already in the target's LIBS.
|
|
||||||
#
|
|
||||||
# We need to run cargo unconditionally, because cargo is the only thing that
|
|
||||||
# has full visibility into how changes in Rust sources might affect the final
|
|
||||||
# build.
|
|
||||||
force-cargo-build:
|
|
||||||
$(REPORT_BUILD)
|
|
||||||
env CARGO_TARGET_DIR=. RUSTC=$(RUSTC) $(CARGO) build $(cargo_build_flags) --
|
|
||||||
|
|
||||||
$(RUST_LIBRARY_FILE): force-cargo-build
|
|
||||||
endif # CARGO_FILE
|
|
||||||
endif # MOZ_RUST
|
|
||||||
|
|
||||||
$(SOBJS):
|
$(SOBJS):
|
||||||
$(REPORT_BUILD)
|
$(REPORT_BUILD)
|
||||||
$(AS) -o $@ $(DEFINES) $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
|
$(AS) -o $@ $(DEFINES) $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
|
||||||
|
|
|
||||||
|
|
@ -35,10 +35,6 @@ if CONFIG['MOZ_WEBM_ENCODER']:
|
||||||
'TestWebMWriter.cpp',
|
'TestWebMWriter.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_RUST']:
|
|
||||||
UNIFIED_SOURCES += ['TestRust.cpp',]
|
|
||||||
|
|
||||||
|
|
||||||
TEST_HARNESS_FILES.gtest += [
|
TEST_HARNESS_FILES.gtest += [
|
||||||
'../test/gizmo-frag.mp4',
|
'../test/gizmo-frag.mp4',
|
||||||
'../test/gizmo.mp4',
|
'../test/gizmo.mp4',
|
||||||
|
|
|
||||||
|
|
@ -37,13 +37,4 @@ TEST_HARNESS_FILES.gtest += [
|
||||||
'test_case_1351094.mp4',
|
'test_case_1351094.mp4',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_RUST']:
|
|
||||||
UNIFIED_SOURCES += ['TestMP4Rust.cpp',]
|
|
||||||
TEST_HARNESS_FILES.gtest += [
|
|
||||||
'../../../dom/media/test/street.mp4',
|
|
||||||
]
|
|
||||||
LOCAL_INCLUDES += [
|
|
||||||
'../binding/include',
|
|
||||||
]
|
|
||||||
|
|
||||||
FINAL_LIBRARY = 'xul-gtest'
|
FINAL_LIBRARY = 'xul-gtest'
|
||||||
|
|
|
||||||
|
|
@ -80,11 +80,6 @@ SOURCES += [
|
||||||
'system/core/libutils/VectorImpl.cpp',
|
'system/core/libutils/VectorImpl.cpp',
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG['MOZ_RUST']:
|
|
||||||
EXPORTS += [
|
|
||||||
'binding/include/mp4parse.h',
|
|
||||||
]
|
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
UNIFIED_SOURCES += [
|
||||||
'binding/Adts.cpp',
|
'binding/Adts.cpp',
|
||||||
'binding/AnnexB.cpp',
|
'binding/AnnexB.cpp',
|
||||||
|
|
|
||||||
|
|
@ -6060,7 +6060,6 @@ export MOZ_ZLIB_CFLAGS
|
||||||
export MOZ_ZLIB_LIBS
|
export MOZ_ZLIB_LIBS
|
||||||
export MOZ_APP_NAME
|
export MOZ_APP_NAME
|
||||||
export MOZ_APP_REMOTINGNAME
|
export MOZ_APP_REMOTINGNAME
|
||||||
export RUSTC
|
|
||||||
export MOZILLA_CENTRAL_PATH=$_topsrcdir
|
export MOZILLA_CENTRAL_PATH=$_topsrcdir
|
||||||
export STLPORT_CPPFLAGS
|
export STLPORT_CPPFLAGS
|
||||||
export STLPORT_LIBS
|
export STLPORT_LIBS
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,6 @@ from ..frontend.data import (
|
||||||
ObjdirPreprocessedFiles,
|
ObjdirPreprocessedFiles,
|
||||||
PerSourceFlag,
|
PerSourceFlag,
|
||||||
Program,
|
Program,
|
||||||
RustLibrary,
|
|
||||||
SharedLibrary,
|
SharedLibrary,
|
||||||
SimpleProgram,
|
SimpleProgram,
|
||||||
Sources,
|
Sources,
|
||||||
|
|
@ -574,12 +573,6 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
elif isinstance(obj, RustLibrary):
|
|
||||||
self.backend_input_files.add(obj.cargo_file)
|
|
||||||
self._process_rust_library(obj, backend_file)
|
|
||||||
# No need to call _process_linked_libraries, because Rust
|
|
||||||
# libraries are self-contained objects at this point.
|
|
||||||
|
|
||||||
elif isinstance(obj, SharedLibrary):
|
elif isinstance(obj, SharedLibrary):
|
||||||
self._process_shared_library(obj, backend_file)
|
self._process_shared_library(obj, backend_file)
|
||||||
self._process_linked_libraries(obj, backend_file)
|
self._process_linked_libraries(obj, backend_file)
|
||||||
|
|
@ -1172,10 +1165,6 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
if libdef.no_expand_lib:
|
if libdef.no_expand_lib:
|
||||||
backend_file.write('NO_EXPAND_LIBS := 1\n')
|
backend_file.write('NO_EXPAND_LIBS := 1\n')
|
||||||
|
|
||||||
def _process_rust_library(self, libdef, backend_file):
|
|
||||||
backend_file.write_once('RUST_LIBRARY_FILE := %s\n' % libdef.import_name)
|
|
||||||
backend_file.write('CARGO_FILE := $(srcdir)/Cargo.toml')
|
|
||||||
|
|
||||||
def _process_host_library(self, libdef, backend_file):
|
def _process_host_library(self, libdef, backend_file):
|
||||||
backend_file.write('HOST_LIBRARY_NAME = %s\n' % libdef.basename)
|
backend_file.write('HOST_LIBRARY_NAME = %s\n' % libdef.basename)
|
||||||
|
|
||||||
|
|
@ -1186,7 +1175,7 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
def _process_linked_libraries(self, obj, backend_file):
|
def _process_linked_libraries(self, obj, backend_file):
|
||||||
def write_shared_and_system_libs(lib):
|
def write_shared_and_system_libs(lib):
|
||||||
for l in lib.linked_libraries:
|
for l in lib.linked_libraries:
|
||||||
if isinstance(l, (StaticLibrary, RustLibrary)):
|
if isinstance(l, StaticLibrary):
|
||||||
write_shared_and_system_libs(l)
|
write_shared_and_system_libs(l)
|
||||||
else:
|
else:
|
||||||
backend_file.write_once('SHARED_LIBS += %s/%s\n'
|
backend_file.write_once('SHARED_LIBS += %s/%s\n'
|
||||||
|
|
@ -1208,11 +1197,7 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
self._build_target_for_obj(lib))
|
self._build_target_for_obj(lib))
|
||||||
relpath = pretty_relpath(lib)
|
relpath = pretty_relpath(lib)
|
||||||
if isinstance(obj, Library):
|
if isinstance(obj, Library):
|
||||||
if isinstance(lib, RustLibrary):
|
if isinstance(lib, StaticLibrary):
|
||||||
# We don't need to do anything here; we will handle
|
|
||||||
# linkage for any RustLibrary elsewhere.
|
|
||||||
continue
|
|
||||||
elif isinstance(lib, StaticLibrary):
|
|
||||||
backend_file.write_once('STATIC_LIBS += %s/%s\n'
|
backend_file.write_once('STATIC_LIBS += %s/%s\n'
|
||||||
% (relpath, lib.import_name))
|
% (relpath, lib.import_name))
|
||||||
if isinstance(obj, SharedLibrary):
|
if isinstance(obj, SharedLibrary):
|
||||||
|
|
@ -1235,12 +1220,6 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
backend_file.write_once('HOST_LIBS += %s/%s\n'
|
backend_file.write_once('HOST_LIBS += %s/%s\n'
|
||||||
% (relpath, lib.import_name))
|
% (relpath, lib.import_name))
|
||||||
|
|
||||||
# We have to link any Rust libraries after all intermediate static
|
|
||||||
# libraries have been listed to ensure that the Rust libraries are
|
|
||||||
# searched after the C/C++ objects that might reference Rust symbols.
|
|
||||||
if isinstance(obj, SharedLibrary):
|
|
||||||
self._process_rust_libraries(obj, backend_file, pretty_relpath)
|
|
||||||
|
|
||||||
for lib in obj.linked_system_libs:
|
for lib in obj.linked_system_libs:
|
||||||
if obj.KIND == 'target':
|
if obj.KIND == 'target':
|
||||||
backend_file.write_once('OS_LIBS += %s\n' % lib)
|
backend_file.write_once('OS_LIBS += %s\n' % lib)
|
||||||
|
|
@ -1250,23 +1229,6 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
# Process library-based defines
|
# Process library-based defines
|
||||||
self._process_defines(obj.lib_defines, backend_file)
|
self._process_defines(obj.lib_defines, backend_file)
|
||||||
|
|
||||||
def _process_rust_libraries(self, obj, backend_file, pretty_relpath):
|
|
||||||
assert isinstance(obj, SharedLibrary)
|
|
||||||
|
|
||||||
# If this library does not depend on any Rust libraries, then we are done.
|
|
||||||
direct_linked = [l for l in obj.linked_libraries if isinstance(l, RustLibrary)]
|
|
||||||
if not direct_linked:
|
|
||||||
return
|
|
||||||
|
|
||||||
# We should have already checked this in Linkable.link_library.
|
|
||||||
assert len(direct_linked) == 1
|
|
||||||
|
|
||||||
# TODO: see bug 1310063 for checking dependencies are set up correctly.
|
|
||||||
|
|
||||||
direct_linked = direct_linked[0]
|
|
||||||
backend_file.write('RUST_STATIC_LIB_FOR_SHARED_LIB := %s/%s\n' %
|
|
||||||
(pretty_relpath(direct_linked), direct_linked.import_name))
|
|
||||||
|
|
||||||
def _process_final_target_files(self, obj, files, backend_file):
|
def _process_final_target_files(self, obj, files, backend_file):
|
||||||
target = obj.install_target
|
target = obj.install_target
|
||||||
path = mozpath.basedir(target, (
|
path = mozpath.basedir(target, (
|
||||||
|
|
@ -1445,11 +1407,6 @@ class RecursiveMakeBackend(CommonBackend):
|
||||||
|
|
||||||
self._makefile_out_count += 1
|
self._makefile_out_count += 1
|
||||||
|
|
||||||
def _handle_linked_rust_crates(self, obj, extern_crate_file):
|
|
||||||
backend_file = self._get_backend_file_for(obj)
|
|
||||||
|
|
||||||
backend_file.write('RS_STATICLIB_CRATE_SRC := %s\n' % extern_crate_file)
|
|
||||||
|
|
||||||
def _handle_ipdl_sources(self, ipdl_dir, sorted_ipdl_sources,
|
def _handle_ipdl_sources(self, ipdl_dir, sorted_ipdl_sources,
|
||||||
unified_ipdl_cppsrcs_mapping):
|
unified_ipdl_cppsrcs_mapping):
|
||||||
# Write out a master list of all IPDL source files.
|
# Write out a master list of all IPDL source files.
|
||||||
|
|
|
||||||
|
|
@ -310,10 +310,6 @@ class LinkageWrongKindError(Exception):
|
||||||
"""Error thrown when trying to link objects of the wrong kind"""
|
"""Error thrown when trying to link objects of the wrong kind"""
|
||||||
|
|
||||||
|
|
||||||
class LinkageMultipleRustLibrariesError(Exception):
|
|
||||||
"""Error thrown when trying to link multiple Rust libraries to an object"""
|
|
||||||
|
|
||||||
|
|
||||||
class Linkable(ContextDerived):
|
class Linkable(ContextDerived):
|
||||||
"""Generic context derived container object for programs and libraries"""
|
"""Generic context derived container object for programs and libraries"""
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
|
@ -337,13 +333,6 @@ class Linkable(ContextDerived):
|
||||||
'Linkable.link_library() does not take components.')
|
'Linkable.link_library() does not take components.')
|
||||||
if obj.KIND != self.KIND:
|
if obj.KIND != self.KIND:
|
||||||
raise LinkageWrongKindError('%s != %s' % (obj.KIND, self.KIND))
|
raise LinkageWrongKindError('%s != %s' % (obj.KIND, self.KIND))
|
||||||
# Linking multiple Rust libraries into an object would result in
|
|
||||||
# multiple copies of the Rust standard library, as well as linking
|
|
||||||
# errors from duplicate symbols.
|
|
||||||
if isinstance(obj, RustLibrary) and any(isinstance(l, RustLibrary)
|
|
||||||
for l in self.linked_libraries):
|
|
||||||
raise LinkageMultipleRustLibrariesError("Cannot link multiple Rust libraries into %s",
|
|
||||||
self)
|
|
||||||
self.linked_libraries.append(obj)
|
self.linked_libraries.append(obj)
|
||||||
if obj.cxx_link:
|
if obj.cxx_link:
|
||||||
self.cxx_link = True
|
self.cxx_link = True
|
||||||
|
|
@ -474,40 +463,6 @@ class StaticLibrary(Library):
|
||||||
self.no_expand_lib = no_expand_lib
|
self.no_expand_lib = no_expand_lib
|
||||||
|
|
||||||
|
|
||||||
class RustLibrary(StaticLibrary):
|
|
||||||
"""Context derived container object for a static library"""
|
|
||||||
__slots__ = (
|
|
||||||
'cargo_file',
|
|
||||||
'crate_type',
|
|
||||||
'dependencies',
|
|
||||||
'deps_path',
|
|
||||||
)
|
|
||||||
|
|
||||||
def __init__(self, context, basename, cargo_file, crate_type, dependencies, **args):
|
|
||||||
StaticLibrary.__init__(self, context, basename, **args)
|
|
||||||
self.cargo_file = cargo_file
|
|
||||||
self.crate_type = crate_type
|
|
||||||
# We need to adjust our naming here because cargo replaces '-' in
|
|
||||||
# package names defined in Cargo.toml with underscores in actual
|
|
||||||
# filenames. But we need to keep the basename consistent because
|
|
||||||
# many other things in the build system depend on that.
|
|
||||||
assert self.crate_type == 'staticlib'
|
|
||||||
self.lib_name = '%s%s%s' % (context.config.lib_prefix,
|
|
||||||
basename.replace('-', '_'),
|
|
||||||
context.config.lib_suffix)
|
|
||||||
self.dependencies = dependencies
|
|
||||||
# cargo creates several directories and places its build artifacts
|
|
||||||
# in those directories. The directory structure depends not only
|
|
||||||
# on the target, but also what sort of build we are doing.
|
|
||||||
rust_build_kind = 'release'
|
|
||||||
if context.config.substs.get('MOZ_DEBUG'):
|
|
||||||
rust_build_kind = 'debug'
|
|
||||||
build_dir = mozpath.join(context.config.substs['RUST_TARGET'],
|
|
||||||
rust_build_kind)
|
|
||||||
self.import_name = mozpath.join(build_dir, self.lib_name)
|
|
||||||
self.deps_path = mozpath.join(build_dir, 'deps')
|
|
||||||
|
|
||||||
|
|
||||||
class SharedLibrary(Library):
|
class SharedLibrary(Library):
|
||||||
"""Context derived container object for a shared library"""
|
"""Context derived container object for a shared library"""
|
||||||
__slots__ = (
|
__slots__ = (
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ from .data import (
|
||||||
PreprocessedTestWebIDLFile,
|
PreprocessedTestWebIDLFile,
|
||||||
PreprocessedWebIDLFile,
|
PreprocessedWebIDLFile,
|
||||||
Program,
|
Program,
|
||||||
RustLibrary,
|
|
||||||
SdkFiles,
|
SdkFiles,
|
||||||
SharedLibrary,
|
SharedLibrary,
|
||||||
SimpleProgram,
|
SimpleProgram,
|
||||||
|
|
@ -198,7 +197,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||||
def _emit_libs_derived(self, contexts):
|
def _emit_libs_derived(self, contexts):
|
||||||
# First do FINAL_LIBRARY linkage.
|
# First do FINAL_LIBRARY linkage.
|
||||||
for lib in (l for libs in self._libs.values() for l in libs):
|
for lib in (l for libs in self._libs.values() for l in libs):
|
||||||
if not isinstance(lib, (StaticLibrary, RustLibrary)) or not lib.link_into:
|
if not isinstance(lib, StaticLibrary) or not lib.link_into:
|
||||||
continue
|
continue
|
||||||
if lib.link_into not in self._libs:
|
if lib.link_into not in self._libs:
|
||||||
raise SandboxValidationError(
|
raise SandboxValidationError(
|
||||||
|
|
@ -408,66 +407,6 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||||
'%s %s of crate %s refers to a non-existent path' % (description, dep_crate_name, crate_name),
|
'%s %s of crate %s refers to a non-existent path' % (description, dep_crate_name, crate_name),
|
||||||
context)
|
context)
|
||||||
|
|
||||||
def _rust_library(self, context, libname, static_args):
|
|
||||||
# We need to note any Rust library for linking purposes.
|
|
||||||
cargo_file = mozpath.join(context.srcdir, 'Cargo.toml')
|
|
||||||
if not os.path.exists(cargo_file):
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'No Cargo.toml file found in %s' % cargo_file, context)
|
|
||||||
|
|
||||||
config = self._parse_cargo_file(cargo_file)
|
|
||||||
crate_name = config['package']['name']
|
|
||||||
|
|
||||||
if crate_name != libname:
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'library %s does not match Cargo.toml-defined package %s' % (libname, crate_name),
|
|
||||||
context)
|
|
||||||
|
|
||||||
# Check that the [lib.crate-type] field is correct
|
|
||||||
lib_section = config.get('lib', None)
|
|
||||||
if not lib_section:
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'Cargo.toml for %s has no [lib] section' % libname,
|
|
||||||
context)
|
|
||||||
|
|
||||||
crate_type = lib_section.get('crate-type', None)
|
|
||||||
if not crate_type:
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'Can\'t determine a crate-type for %s from Cargo.toml' % libname,
|
|
||||||
context)
|
|
||||||
|
|
||||||
crate_type = crate_type[0]
|
|
||||||
if crate_type != 'staticlib':
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'crate-type %s is not permitted for %s' % (crate_type, libname),
|
|
||||||
context)
|
|
||||||
|
|
||||||
# Check that the [profile.{dev,release}.panic] field is "abort"
|
|
||||||
profile_section = config.get('profile', None)
|
|
||||||
if not profile_section:
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'Cargo.toml for %s has no [profile] section' % libname,
|
|
||||||
context)
|
|
||||||
|
|
||||||
for profile_name in ['dev', 'release']:
|
|
||||||
profile = profile_section.get(profile_name, None)
|
|
||||||
if not profile:
|
|
||||||
raise SandboxValidationError(
|
|
||||||
'Cargo.toml for %s has no [profile.%s] section' % (libname, profile_name),
|
|
||||||
context)
|
|
||||||
|
|
||||||
panic = profile.get('panic', None)
|
|
||||||
if panic != 'abort':
|
|
||||||
raise SandboxValidationError(
|
|
||||||
('Cargo.toml for %s does not specify `panic = "abort"`'
|
|
||||||
' in [profile.%s] section') % (libname, profile_name),
|
|
||||||
context)
|
|
||||||
|
|
||||||
dependencies = set(config.get('dependencies', {}).iterkeys())
|
|
||||||
|
|
||||||
return RustLibrary(context, libname, cargo_file, crate_type,
|
|
||||||
dependencies, **static_args)
|
|
||||||
|
|
||||||
def _handle_linkables(self, context, passthru, generated_files):
|
def _handle_linkables(self, context, passthru, generated_files):
|
||||||
linkables = []
|
linkables = []
|
||||||
host_linkables = []
|
host_linkables = []
|
||||||
|
|
@ -688,11 +627,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
||||||
'generate_symbols_file', lib.symbols_file,
|
'generate_symbols_file', lib.symbols_file,
|
||||||
[symbols_file], defines)
|
[symbols_file], defines)
|
||||||
if static_lib:
|
if static_lib:
|
||||||
is_rust_library = context.get('IS_RUST_LIBRARY')
|
lib = StaticLibrary(context, libname, **static_args)
|
||||||
if is_rust_library:
|
|
||||||
lib = self._rust_library(context, libname, static_args)
|
|
||||||
else:
|
|
||||||
lib = StaticLibrary(context, libname, **static_args)
|
|
||||||
self._libs[libname].append(lib)
|
self._libs[libname].append(lib)
|
||||||
self._linkage.append((context, lib, 'USE_LIBS'))
|
self._linkage.append((context, lib, 'USE_LIBS'))
|
||||||
linkables.append(lib)
|
linkables.append(lib)
|
||||||
|
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
deep-crate = { version = "0.1.0", path = "the/depths" }
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "shallow-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "deep-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
shallow-crate = { path = "../../shallow" }
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
Library('test')
|
|
||||||
|
|
||||||
DIRS += [
|
|
||||||
'rust1',
|
|
||||||
'rust2',
|
|
||||||
]
|
|
||||||
|
|
||||||
USE_LIBS += [
|
|
||||||
'rust1',
|
|
||||||
'rust2',
|
|
||||||
]
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "rust1"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
RustLibrary('rust1')
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "rust2"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
RustLibrary('rust2')
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["dylib"]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "deterministic-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
panic = "abort"
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "random-crate"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = [
|
|
||||||
"Nobody <nobody@mozilla.org>",
|
|
||||||
]
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|
||||||
[profile.dev]
|
|
||||||
panic = "unwind"
|
|
||||||
|
|
||||||
[profile.release]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Any copyright is dedicated to the Public Domain.
|
|
||||||
# http://creativecommons.org/publicdomain/zero/1.0/
|
|
||||||
|
|
||||||
@template
|
|
||||||
def Library(name):
|
|
||||||
'''Template for libraries.'''
|
|
||||||
LIBRARY_NAME = name
|
|
||||||
|
|
||||||
|
|
||||||
@template
|
|
||||||
def RustLibrary(name):
|
|
||||||
'''Template for Rust libraries.'''
|
|
||||||
Library(name)
|
|
||||||
|
|
||||||
IS_RUST_LIBRARY = True
|
|
||||||
|
|
||||||
|
|
||||||
RustLibrary('random-crate')
|
|
||||||
|
|
@ -31,7 +31,6 @@ from mozbuild.frontend.data import (
|
||||||
LinkageMultipleRustLibrariesError,
|
LinkageMultipleRustLibrariesError,
|
||||||
LocalInclude,
|
LocalInclude,
|
||||||
Program,
|
Program,
|
||||||
RustLibrary,
|
|
||||||
SdkFiles,
|
SdkFiles,
|
||||||
SharedLibrary,
|
SharedLibrary,
|
||||||
SimpleProgram,
|
SimpleProgram,
|
||||||
|
|
@ -1021,78 +1020,6 @@ class TestEmitterBasic(unittest.TestCase):
|
||||||
'Only source directory paths allowed in FINAL_TARGET_PP_FILES:'):
|
'Only source directory paths allowed in FINAL_TARGET_PP_FILES:'):
|
||||||
self.read_topsrcdir(reader)
|
self.read_topsrcdir(reader)
|
||||||
|
|
||||||
def test_rust_library_no_cargo_toml(self):
|
|
||||||
'''Test that defining a RustLibrary without a Cargo.toml fails.'''
|
|
||||||
reader = self.reader('rust-library-no-cargo-toml')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'No Cargo.toml file found'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_name_mismatch(self):
|
|
||||||
'''Test that defining a RustLibrary that doesn't match Cargo.toml fails.'''
|
|
||||||
reader = self.reader('rust-library-name-mismatch')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'library.*does not match Cargo.toml-defined package'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_no_lib_section(self):
|
|
||||||
'''Test that a RustLibrary Cargo.toml with no [lib] section fails.'''
|
|
||||||
reader = self.reader('rust-library-no-lib-section')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'Cargo.toml for.* has no \\[lib\\] section'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_no_profile_section(self):
|
|
||||||
'''Test that a RustLibrary Cargo.toml with no [profile] section fails.'''
|
|
||||||
reader = self.reader('rust-library-no-profile-section')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'Cargo.toml for.* has no \\[profile\\.dev\\] section'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_invalid_crate_type(self):
|
|
||||||
'''Test that a RustLibrary Cargo.toml has a permitted crate-type.'''
|
|
||||||
reader = self.reader('rust-library-invalid-crate-type')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'crate-type.* is not permitted'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_non_abort_panic(self):
|
|
||||||
'''Test that a RustLibrary Cargo.toml has `panic = "abort" set'''
|
|
||||||
reader = self.reader('rust-library-non-abort-panic')
|
|
||||||
with self.assertRaisesRegexp(SandboxValidationError,
|
|
||||||
'does not specify `panic = "abort"`'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_rust_library_dash_folding(self):
|
|
||||||
'''Test that on-disk names of RustLibrary objects convert dashes to underscores.'''
|
|
||||||
reader = self.reader('rust-library-dash-folding',
|
|
||||||
extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
|
|
||||||
objs = self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
self.assertEqual(len(objs), 1)
|
|
||||||
lib = objs[0]
|
|
||||||
self.assertIsInstance(lib, RustLibrary)
|
|
||||||
self.assertRegexpMatches(lib.lib_name, "random_crate")
|
|
||||||
self.assertRegexpMatches(lib.import_name, "random_crate")
|
|
||||||
self.assertRegexpMatches(lib.basename, "random-crate")
|
|
||||||
|
|
||||||
def test_multiple_rust_libraries(self):
|
|
||||||
'''Test that linking multiple Rust libraries throws an error'''
|
|
||||||
reader = self.reader('multiple-rust-libraries',
|
|
||||||
extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
|
|
||||||
with self.assertRaisesRegexp(LinkageMultipleRustLibrariesError,
|
|
||||||
'Cannot link multiple Rust libraries'):
|
|
||||||
self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
def test_crate_dependency_path_resolution(self):
|
|
||||||
'''Test recursive dependencies resolve with the correct paths.'''
|
|
||||||
reader = self.reader('crate-dependency-path-resolution',
|
|
||||||
extra_substs=dict(RUST_TARGET='i686-pc-windows-msvc'))
|
|
||||||
objs = self.read_topsrcdir(reader)
|
|
||||||
|
|
||||||
self.assertEqual(len(objs), 1)
|
|
||||||
self.assertIsInstance(objs[0], RustLibrary)
|
|
||||||
|
|
||||||
def test_android_res_dirs(self):
|
def test_android_res_dirs(self):
|
||||||
"""Test that ANDROID_RES_DIRS works properly."""
|
"""Test that ANDROID_RES_DIRS works properly."""
|
||||||
reader = self.reader('android-res-dirs')
|
reader = self.reader('android-res-dirs')
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"2879af3c0512f976015d532e2d768f04ff22fdcf8745b69b955b78fda321c3fb",".travis.yml":"81545ce3c6c72111a68434464c3f9fa8df9cbe39759a081fac527628ab21ae0c","COPYING":"01c266bced4a434da0051174d6bee16a4c82cf634e2679b6155d40d75012390f","Cargo.toml":"a7282931b50dff2e463f82baaed95a9d76636bc0fef3e921acd8ca69eab32b83","LICENSE-MIT":"0f96a83840e146e43c0ec96a22ec1f392e0680e6c1226e6f3ba87e0740af850f","Makefile":"a45a128685a2ae7d4fa39d310786674417ee113055ef290a11f88002285865fc","README.md":"fbcc46b6d0a585096737f50922818b59016b69d959b05f1b29863b2af8e4da43","UNLICENSE":"7e12e5df4bae12cb21581ba157ced20e1986a0508dd10d0e8a4ab9a4cf94e85c","benches/bench.rs":"f583692d829c8dfe19b1d5b9e968ccf5c74d6733367ca183edff74041a6afedd","session.vim":"95cb1d7caf0ff7fbe76ec911988d908ddd883381c925ba64b537695bc9f021c4","src/lib.rs":"ef9e7a218fa3a4912c47f6840d32b975940d98277b6c9be85e8d7d045552eb87","src/new.rs":"161c21b7ebb5668c7cc70b46b0eb37709e06bb9c854f2fdfc6ce3d3babcbf3de"},"package":"0fc10e8cc6b2580fda3f36eb6dc5316657f812a3df879a44a66fc9f0fdbc4855"}
|
|
||||||
0
third_party/rust/byteorder/.cargo-ok
vendored
0
third_party/rust/byteorder/.cargo-ok
vendored
6
third_party/rust/byteorder/.gitignore
vendored
6
third_party/rust/byteorder/.gitignore
vendored
|
|
@ -1,6 +0,0 @@
|
||||||
.*.swp
|
|
||||||
doc
|
|
||||||
tags
|
|
||||||
build
|
|
||||||
target
|
|
||||||
Cargo.lock
|
|
||||||
15
third_party/rust/byteorder/.travis.yml
vendored
15
third_party/rust/byteorder/.travis.yml
vendored
|
|
@ -1,15 +0,0 @@
|
||||||
language: rust
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- rust: "nightly"
|
|
||||||
env: TEST_SUITE=suite_nightly
|
|
||||||
- rust: "beta"
|
|
||||||
env: TEST_SUITE=suite_beta
|
|
||||||
- rust: "stable"
|
|
||||||
env: TEST_SUITE=suite_stable
|
|
||||||
script:
|
|
||||||
- cargo build --verbose
|
|
||||||
- cargo test --verbose
|
|
||||||
- if [ "$TEST_SUITE" = "suite_nightly" ]; then
|
|
||||||
cargo bench --verbose;
|
|
||||||
fi
|
|
||||||
3
third_party/rust/byteorder/COPYING
vendored
3
third_party/rust/byteorder/COPYING
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
This project is dual-licensed under the Unlicense and MIT licenses.
|
|
||||||
|
|
||||||
You may use this code under the terms of either license.
|
|
||||||
25
third_party/rust/byteorder/Cargo.toml
vendored
25
third_party/rust/byteorder/Cargo.toml
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "byteorder"
|
|
||||||
version = "0.5.3" #:version
|
|
||||||
authors = ["Andrew Gallant <jamslam@gmail.com>"]
|
|
||||||
description = "Library for reading/writing numbers in big-endian and little-endian."
|
|
||||||
documentation = "http://burntsushi.net/rustdoc/byteorder/"
|
|
||||||
homepage = "https://github.com/BurntSushi/byteorder"
|
|
||||||
repository = "https://github.com/BurntSushi/byteorder"
|
|
||||||
readme = "README.md"
|
|
||||||
keywords = ["byte", "endian", "big-endian", "little-endian", "binary"]
|
|
||||||
license = "Unlicense/MIT"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
name = "byteorder"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
quickcheck = "0.2"
|
|
||||||
rand = "0.3"
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["std"]
|
|
||||||
std = []
|
|
||||||
|
|
||||||
[profile.bench]
|
|
||||||
opt-level = 3
|
|
||||||
21
third_party/rust/byteorder/LICENSE-MIT
vendored
21
third_party/rust/byteorder/LICENSE-MIT
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
The MIT License (MIT)
|
|
||||||
|
|
||||||
Copyright (c) 2015 Andrew Gallant
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
14
third_party/rust/byteorder/Makefile
vendored
14
third_party/rust/byteorder/Makefile
vendored
|
|
@ -1,14 +0,0 @@
|
||||||
all:
|
|
||||||
echo Nothing to do...
|
|
||||||
|
|
||||||
ctags:
|
|
||||||
ctags --recurse --options=ctags.rust --languages=Rust
|
|
||||||
|
|
||||||
docs:
|
|
||||||
cargo doc
|
|
||||||
in-dir ./target/doc fix-perms
|
|
||||||
rscp ./target/doc/* gopher:~/www/burntsushi.net/rustdoc/
|
|
||||||
|
|
||||||
push:
|
|
||||||
git push origin master
|
|
||||||
git push github master
|
|
||||||
59
third_party/rust/byteorder/README.md
vendored
59
third_party/rust/byteorder/README.md
vendored
|
|
@ -1,59 +0,0 @@
|
||||||
This crate provides convenience methods for encoding and decoding numbers in
|
|
||||||
either big-endian or little-endian order. This is meant to replace the old
|
|
||||||
methods defined on the standard library `Reader` and `Writer` traits.
|
|
||||||
|
|
||||||
[](https://travis-ci.org/BurntSushi/byteorder)
|
|
||||||
[](https://crates.io/crates/byteorder)
|
|
||||||
|
|
||||||
Dual-licensed under MIT or the [UNLICENSE](http://unlicense.org).
|
|
||||||
|
|
||||||
|
|
||||||
### Documentation
|
|
||||||
|
|
||||||
[http://burntsushi.net/rustdoc/byteorder/](http://burntsushi.net/rustdoc/byteorder/).
|
|
||||||
|
|
||||||
The documentation includes examples.
|
|
||||||
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
This crate works with Cargo and is on
|
|
||||||
[crates.io](https://crates.io/crates/byteorder). The package is regularly
|
|
||||||
updated. Add it to your `Cargo.toml` like so:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
byteorder = "0.5"
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to augment existing `Read` and `Write` traits, then import the
|
|
||||||
extension methods like so:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate byteorder;
|
|
||||||
|
|
||||||
use byteorder::{ReadBytesExt, WriteBytesExt, BigEndian, LittleEndian};
|
|
||||||
```
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use std::io::Cursor;
|
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
|
||||||
|
|
||||||
let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
|
|
||||||
// Note that we use type parameters to indicate which kind of byte order
|
|
||||||
// we want!
|
|
||||||
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
```
|
|
||||||
|
|
||||||
### `no_std` crates
|
|
||||||
|
|
||||||
This crate has a feature, `std`, that is enabled by default. To use this crate
|
|
||||||
in a `no_std` context, add the following to your `Cargo.toml`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
byteorder = { version = "0.5", default-features = false }
|
|
||||||
```
|
|
||||||
24
third_party/rust/byteorder/UNLICENSE
vendored
24
third_party/rust/byteorder/UNLICENSE
vendored
|
|
@ -1,24 +0,0 @@
|
||||||
This is free and unencumbered software released into the public domain.
|
|
||||||
|
|
||||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
||||||
distribute this software, either in source code form or as a compiled
|
|
||||||
binary, for any purpose, commercial or non-commercial, and by any
|
|
||||||
means.
|
|
||||||
|
|
||||||
In jurisdictions that recognize copyright laws, the author or authors
|
|
||||||
of this software dedicate any and all copyright interest in the
|
|
||||||
software to the public domain. We make this dedication for the benefit
|
|
||||||
of the public at large and to the detriment of our heirs and
|
|
||||||
successors. We intend this dedication to be an overt act of
|
|
||||||
relinquishment in perpetuity of all present and future rights to this
|
|
||||||
software under copyright law.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
||||||
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
||||||
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
||||||
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
||||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
For more information, please refer to <http://unlicense.org/>
|
|
||||||
148
third_party/rust/byteorder/benches/bench.rs
vendored
148
third_party/rust/byteorder/benches/bench.rs
vendored
|
|
@ -1,148 +0,0 @@
|
||||||
#![feature(test)]
|
|
||||||
|
|
||||||
extern crate byteorder;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
macro_rules! bench_num {
|
|
||||||
($name:ident, $read:ident, $bytes:expr, $data:expr) => (
|
|
||||||
mod $name {
|
|
||||||
use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
|
|
||||||
use super::test::Bencher;
|
|
||||||
use super::test::black_box as bb;
|
|
||||||
|
|
||||||
const NITER: usize = 100_000;
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_big_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(BigEndian::$read(&buf, $bytes));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_little_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(LittleEndian::$read(&buf, $bytes));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_native_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(NativeEndian::$read(&buf, $bytes));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($ty:ident, $max:ident,
|
|
||||||
$read:ident, $write:ident, $size:expr, $data:expr) => (
|
|
||||||
mod $ty {
|
|
||||||
use std::$ty;
|
|
||||||
use byteorder::{ByteOrder, BigEndian, NativeEndian, LittleEndian};
|
|
||||||
use super::test::Bencher;
|
|
||||||
use super::test::black_box as bb;
|
|
||||||
|
|
||||||
const NITER: usize = 100_000;
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_big_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(BigEndian::$read(&buf));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_little_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(LittleEndian::$read(&buf));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn read_native_endian(b: &mut Bencher) {
|
|
||||||
let buf = $data;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(NativeEndian::$read(&buf));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn write_big_endian(b: &mut Bencher) {
|
|
||||||
let mut buf = $data;
|
|
||||||
let n = $ty::$max;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(BigEndian::$write(&mut buf, n));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn write_little_endian(b: &mut Bencher) {
|
|
||||||
let mut buf = $data;
|
|
||||||
let n = $ty::$max;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(LittleEndian::$write(&mut buf, n));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn write_native_endian(b: &mut Bencher) {
|
|
||||||
let mut buf = $data;
|
|
||||||
let n = $ty::$max;
|
|
||||||
b.iter(|| {
|
|
||||||
for _ in 0..NITER {
|
|
||||||
bb(NativeEndian::$write(&mut buf, n));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bench_num!(u16, MAX, read_u16, write_u16, 2, [1, 2]);
|
|
||||||
bench_num!(i16, MAX, read_i16, write_i16, 2, [1, 2]);
|
|
||||||
bench_num!(u32, MAX, read_u32, write_u32, 4, [1, 2, 3, 4]);
|
|
||||||
bench_num!(i32, MAX, read_i32, write_i32, 4, [1, 2, 3, 4]);
|
|
||||||
bench_num!(u64, MAX, read_u64, write_u64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
|
|
||||||
bench_num!(i64, MAX, read_i64, write_i64, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
|
|
||||||
bench_num!(f32, MAX, read_f32, write_f32, 4, [1, 2, 3, 4]);
|
|
||||||
bench_num!(f64, MAX, read_f64, write_f64, 8,
|
|
||||||
[1, 2, 3, 4, 5, 6, 7, 8]);
|
|
||||||
|
|
||||||
bench_num!(uint_1, read_uint, 1, [1]);
|
|
||||||
bench_num!(uint_2, read_uint, 2, [1, 2]);
|
|
||||||
bench_num!(uint_3, read_uint, 3, [1, 2, 3]);
|
|
||||||
bench_num!(uint_4, read_uint, 4, [1, 2, 3, 4]);
|
|
||||||
bench_num!(uint_5, read_uint, 5, [1, 2, 3, 4, 5]);
|
|
||||||
bench_num!(uint_6, read_uint, 6, [1, 2, 3, 4, 5, 6]);
|
|
||||||
bench_num!(uint_7, read_uint, 7, [1, 2, 3, 4, 5, 6, 7]);
|
|
||||||
bench_num!(uint_8, read_uint, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
|
|
||||||
|
|
||||||
bench_num!(int_1, read_int, 1, [1]);
|
|
||||||
bench_num!(int_2, read_int, 2, [1, 2]);
|
|
||||||
bench_num!(int_3, read_int, 3, [1, 2, 3]);
|
|
||||||
bench_num!(int_4, read_int, 4, [1, 2, 3, 4]);
|
|
||||||
bench_num!(int_5, read_int, 5, [1, 2, 3, 4, 5]);
|
|
||||||
bench_num!(int_6, read_int, 6, [1, 2, 3, 4, 5, 6]);
|
|
||||||
bench_num!(int_7, read_int, 7, [1, 2, 3, 4, 5, 6, 7]);
|
|
||||||
bench_num!(int_8, read_int, 8, [1, 2, 3, 4, 5, 6, 7, 8]);
|
|
||||||
1
third_party/rust/byteorder/session.vim
vendored
1
third_party/rust/byteorder/session.vim
vendored
|
|
@ -1 +0,0 @@
|
||||||
au BufWritePost *.rs silent!make ctags > /dev/null 2>&1
|
|
||||||
802
third_party/rust/byteorder/src/lib.rs
vendored
802
third_party/rust/byteorder/src/lib.rs
vendored
|
|
@ -1,802 +0,0 @@
|
||||||
/*!
|
|
||||||
This crate provides convenience methods for encoding and decoding numbers
|
|
||||||
in either big-endian or little-endian order.
|
|
||||||
|
|
||||||
The organization of the crate is pretty simple. A trait, `ByteOrder`, specifies
|
|
||||||
byte conversion methods for each type of number in Rust (sans numbers that have
|
|
||||||
a platform dependent size like `usize` and `isize`). Two types, `BigEndian`
|
|
||||||
and `LittleEndian` implement these methods. Finally, `ReadBytesExt` and
|
|
||||||
`WriteBytesExt` provide convenience methods available to all types that
|
|
||||||
implement `Read` and `Write`.
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
|
|
||||||
Read unsigned 16 bit big-endian integers from a `Read` type:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use std::io::Cursor;
|
|
||||||
use byteorder::{BigEndian, ReadBytesExt};
|
|
||||||
|
|
||||||
let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
|
|
||||||
// Note that we use type parameters to indicate which kind of byte order
|
|
||||||
// we want!
|
|
||||||
assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
```
|
|
||||||
|
|
||||||
Write unsigned 16 bit little-endian integers to a `Write` type:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
use byteorder::{LittleEndian, WriteBytesExt};
|
|
||||||
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.write_u16::<LittleEndian>(517).unwrap();
|
|
||||||
wtr.write_u16::<LittleEndian>(768).unwrap();
|
|
||||||
assert_eq!(wtr, vec![5, 2, 0, 3]);
|
|
||||||
```
|
|
||||||
*/
|
|
||||||
|
|
||||||
#![crate_name = "byteorder"]
|
|
||||||
#![doc(html_root_url = "http://burntsushi.net/rustdoc/byteorder")]
|
|
||||||
|
|
||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
extern crate core;
|
|
||||||
|
|
||||||
use core::mem::transmute;
|
|
||||||
use core::ptr::copy_nonoverlapping;
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
pub use new::{ReadBytesExt, WriteBytesExt};
|
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
|
||||||
mod new;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn extend_sign(val: u64, nbytes: usize) -> i64 {
|
|
||||||
let shift = (8 - nbytes) * 8;
|
|
||||||
(val << shift) as i64 >> shift
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn unextend_sign(val: i64, nbytes: usize) -> u64 {
|
|
||||||
let shift = (8 - nbytes) * 8;
|
|
||||||
(val << shift) as u64 >> shift
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn pack_size(n: u64) -> usize {
|
|
||||||
if n < 1 << 8 {
|
|
||||||
1
|
|
||||||
} else if n < 1 << 16 {
|
|
||||||
2
|
|
||||||
} else if n < 1 << 24 {
|
|
||||||
3
|
|
||||||
} else if n < 1 << 32 {
|
|
||||||
4
|
|
||||||
} else if n < 1 << 40 {
|
|
||||||
5
|
|
||||||
} else if n < 1 << 48 {
|
|
||||||
6
|
|
||||||
} else if n < 1 << 56 {
|
|
||||||
7
|
|
||||||
} else {
|
|
||||||
8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ByteOrder describes types that can serialize integers as bytes.
|
|
||||||
///
|
|
||||||
/// Note that `Self` does not appear anywhere in this trait's definition!
|
|
||||||
/// Therefore, in order to use it, you'll need to use syntax like
|
|
||||||
/// `T::read_u16(&[0, 1])` where `T` implements `ByteOrder`.
|
|
||||||
///
|
|
||||||
/// This crate provides two types that implement `ByteOrder`: `BigEndian`
|
|
||||||
/// and `LittleEndian`.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Write and read `u32` numbers in little endian order:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use byteorder::{ByteOrder, LittleEndian};
|
|
||||||
///
|
|
||||||
/// let mut buf = [0; 4];
|
|
||||||
/// LittleEndian::write_u32(&mut buf, 1_000_000);
|
|
||||||
/// assert_eq!(1_000_000, LittleEndian::read_u32(&buf));
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// Write and read `i16` numbers in big endian order:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use byteorder::{ByteOrder, BigEndian};
|
|
||||||
///
|
|
||||||
/// let mut buf = [0; 2];
|
|
||||||
/// BigEndian::write_i16(&mut buf, -50_000);
|
|
||||||
/// assert_eq!(-50_000, BigEndian::read_i16(&buf));
|
|
||||||
/// ```
|
|
||||||
pub trait ByteOrder {
|
|
||||||
/// Reads an unsigned 16 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 2`.
|
|
||||||
fn read_u16(buf: &[u8]) -> u16;
|
|
||||||
|
|
||||||
/// Reads an unsigned 32 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
fn read_u32(buf: &[u8]) -> u32;
|
|
||||||
|
|
||||||
/// Reads an unsigned 64 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
fn read_u64(buf: &[u8]) -> u64;
|
|
||||||
|
|
||||||
/// Reads an unsigned n-bytes integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `nbytes < 1` or `nbytes > 8` or
|
|
||||||
/// `buf.len() < nbytes`
|
|
||||||
fn read_uint(buf: &[u8], nbytes: usize) -> u64;
|
|
||||||
|
|
||||||
/// Writes an unsigned 16 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 2`.
|
|
||||||
fn write_u16(buf: &mut [u8], n: u16);
|
|
||||||
|
|
||||||
/// Writes an unsigned 32 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
fn write_u32(buf: &mut [u8], n: u32);
|
|
||||||
|
|
||||||
/// Writes an unsigned 64 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
fn write_u64(buf: &mut [u8], n: u64);
|
|
||||||
|
|
||||||
/// Writes an unsigned integer `n` to `buf` using only `nbytes`.
|
|
||||||
///
|
|
||||||
/// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
|
|
||||||
/// this method panics.
|
|
||||||
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize);
|
|
||||||
|
|
||||||
/// Reads a signed 16 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 2`.
|
|
||||||
#[inline]
|
|
||||||
fn read_i16(buf: &[u8]) -> i16 {
|
|
||||||
Self::read_u16(buf) as i16
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 32 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
#[inline]
|
|
||||||
fn read_i32(buf: &[u8]) -> i32 {
|
|
||||||
Self::read_u32(buf) as i32
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 64 bit integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
#[inline]
|
|
||||||
fn read_i64(buf: &[u8]) -> i64 {
|
|
||||||
Self::read_u64(buf) as i64
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed n-bytes integer from `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `nbytes < 1` or `nbytes > 8` or
|
|
||||||
/// `buf.len() < nbytes`
|
|
||||||
#[inline]
|
|
||||||
fn read_int(buf: &[u8], nbytes: usize) -> i64 {
|
|
||||||
extend_sign(Self::read_uint(buf, nbytes), nbytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a IEEE754 single-precision (4 bytes) floating point number.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
#[inline]
|
|
||||||
fn read_f32(buf: &[u8]) -> f32 {
|
|
||||||
unsafe { transmute(Self::read_u32(buf)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a IEEE754 double-precision (8 bytes) floating point number.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
#[inline]
|
|
||||||
fn read_f64(buf: &[u8]) -> f64 {
|
|
||||||
unsafe { transmute(Self::read_u64(buf)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 16 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 2`.
|
|
||||||
#[inline]
|
|
||||||
fn write_i16(buf: &mut [u8], n: i16) {
|
|
||||||
Self::write_u16(buf, n as u16)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 32 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
#[inline]
|
|
||||||
fn write_i32(buf: &mut [u8], n: i32) {
|
|
||||||
Self::write_u32(buf, n as u32)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 64 bit integer `n` to `buf`.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
#[inline]
|
|
||||||
fn write_i64(buf: &mut [u8], n: i64) {
|
|
||||||
Self::write_u64(buf, n as u64)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed integer `n` to `buf` using only `nbytes`.
|
|
||||||
///
|
|
||||||
/// If `n` is not representable in `nbytes`, or if `nbytes` is `> 8`, then
|
|
||||||
/// this method panics.
|
|
||||||
#[inline]
|
|
||||||
fn write_int(buf: &mut [u8], n: i64, nbytes: usize) {
|
|
||||||
Self::write_uint(buf, unextend_sign(n, nbytes), nbytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a IEEE754 single-precision (4 bytes) floating point number.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 4`.
|
|
||||||
#[inline]
|
|
||||||
fn write_f32(buf: &mut [u8], n: f32) {
|
|
||||||
Self::write_u32(buf, unsafe { transmute(n) })
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a IEEE754 double-precision (8 bytes) floating point number.
|
|
||||||
///
|
|
||||||
/// Panics when `buf.len() < 8`.
|
|
||||||
#[inline]
|
|
||||||
fn write_f64(buf: &mut [u8], n: f64) {
|
|
||||||
Self::write_u64(buf, unsafe { transmute(n) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Defines big-endian serialization.
|
|
||||||
///
|
|
||||||
/// Note that this type has no value constructor. It is used purely at the
|
|
||||||
/// type level.
|
|
||||||
#[allow(missing_copy_implementations)] pub enum BigEndian {}
|
|
||||||
|
|
||||||
/// Defines little-endian serialization.
|
|
||||||
///
|
|
||||||
/// Note that this type has no value constructor. It is used purely at the
|
|
||||||
/// type level.
|
|
||||||
#[allow(missing_copy_implementations)] pub enum LittleEndian {}
|
|
||||||
|
|
||||||
/// Defines network byte order serialization.
|
|
||||||
///
|
|
||||||
/// Network byte order is defined by [RFC 1700][1] to be big-endian, and is
|
|
||||||
/// referred to in several protocol specifications. This type is an alias of
|
|
||||||
/// BigEndian.
|
|
||||||
///
|
|
||||||
/// [1]: https://tools.ietf.org/html/rfc1700
|
|
||||||
///
|
|
||||||
/// Note that this type has no value constructor. It is used purely at the
|
|
||||||
/// type level.
|
|
||||||
pub type NetworkEndian = BigEndian;
|
|
||||||
|
|
||||||
/// Defines system native-endian serialization.
|
|
||||||
///
|
|
||||||
/// Note that this type has no value constructor. It is used purely at the
|
|
||||||
/// type level.
|
|
||||||
#[cfg(target_endian = "little")]
|
|
||||||
pub type NativeEndian = LittleEndian;
|
|
||||||
|
|
||||||
/// Defines system native-endian serialization.
|
|
||||||
///
|
|
||||||
/// Note that this type has no value constructor. It is used purely at the
|
|
||||||
/// type level.
|
|
||||||
#[cfg(target_endian = "big")]
|
|
||||||
pub type NativeEndian = BigEndian;
|
|
||||||
|
|
||||||
macro_rules! read_num_bytes {
|
|
||||||
($ty:ty, $size:expr, $src:expr, $which:ident) => ({
|
|
||||||
assert!($size == ::core::mem::size_of::<$ty>());
|
|
||||||
assert!($size <= $src.len());
|
|
||||||
let mut data: $ty = 0;
|
|
||||||
unsafe {
|
|
||||||
copy_nonoverlapping(
|
|
||||||
$src.as_ptr(),
|
|
||||||
&mut data as *mut $ty as *mut u8,
|
|
||||||
$size);
|
|
||||||
}
|
|
||||||
data.$which()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! write_num_bytes {
|
|
||||||
($ty:ty, $size:expr, $n:expr, $dst:expr, $which:ident) => ({
|
|
||||||
assert!($size <= $dst.len());
|
|
||||||
unsafe {
|
|
||||||
// N.B. https://github.com/rust-lang/rust/issues/22776
|
|
||||||
let bytes = transmute::<_, [u8; $size]>($n.$which());
|
|
||||||
copy_nonoverlapping((&bytes).as_ptr(), $dst.as_mut_ptr(), $size);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ByteOrder for BigEndian {
|
|
||||||
#[inline]
|
|
||||||
fn read_u16(buf: &[u8]) -> u16 {
|
|
||||||
read_num_bytes!(u16, 2, buf, to_be)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_u32(buf: &[u8]) -> u32 {
|
|
||||||
read_num_bytes!(u32, 4, buf, to_be)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_u64(buf: &[u8]) -> u64 {
|
|
||||||
read_num_bytes!(u64, 8, buf, to_be)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
|
|
||||||
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
|
|
||||||
let mut out = [0u8; 8];
|
|
||||||
let ptr_out = out.as_mut_ptr();
|
|
||||||
unsafe {
|
|
||||||
copy_nonoverlapping(
|
|
||||||
buf.as_ptr(), ptr_out.offset((8 - nbytes) as isize), nbytes);
|
|
||||||
(*(ptr_out as *const u64)).to_be()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u16(buf: &mut [u8], n: u16) {
|
|
||||||
write_num_bytes!(u16, 2, n, buf, to_be);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u32(buf: &mut [u8], n: u32) {
|
|
||||||
write_num_bytes!(u32, 4, n, buf, to_be);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u64(buf: &mut [u8], n: u64) {
|
|
||||||
write_num_bytes!(u64, 8, n, buf, to_be);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
|
|
||||||
assert!(pack_size(n) <= nbytes && nbytes <= 8);
|
|
||||||
assert!(nbytes <= buf.len());
|
|
||||||
unsafe {
|
|
||||||
let bytes: [u8; 8] = transmute(n.to_be());
|
|
||||||
copy_nonoverlapping(
|
|
||||||
bytes.as_ptr().offset((8 - nbytes) as isize),
|
|
||||||
buf.as_mut_ptr(),
|
|
||||||
nbytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ByteOrder for LittleEndian {
|
|
||||||
#[inline]
|
|
||||||
fn read_u16(buf: &[u8]) -> u16 {
|
|
||||||
read_num_bytes!(u16, 2, buf, to_le)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_u32(buf: &[u8]) -> u32 {
|
|
||||||
read_num_bytes!(u32, 4, buf, to_le)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_u64(buf: &[u8]) -> u64 {
|
|
||||||
read_num_bytes!(u64, 8, buf, to_le)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn read_uint(buf: &[u8], nbytes: usize) -> u64 {
|
|
||||||
assert!(1 <= nbytes && nbytes <= 8 && nbytes <= buf.len());
|
|
||||||
let mut out = [0u8; 8];
|
|
||||||
let ptr_out = out.as_mut_ptr();
|
|
||||||
unsafe {
|
|
||||||
copy_nonoverlapping(buf.as_ptr(), ptr_out, nbytes);
|
|
||||||
(*(ptr_out as *const u64)).to_le()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u16(buf: &mut [u8], n: u16) {
|
|
||||||
write_num_bytes!(u16, 2, n, buf, to_le);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u32(buf: &mut [u8], n: u32) {
|
|
||||||
write_num_bytes!(u32, 4, n, buf, to_le);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_u64(buf: &mut [u8], n: u64) {
|
|
||||||
write_num_bytes!(u64, 8, n, buf, to_le);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn write_uint(buf: &mut [u8], n: u64, nbytes: usize) {
|
|
||||||
assert!(pack_size(n as u64) <= nbytes && nbytes <= 8);
|
|
||||||
assert!(nbytes <= buf.len());
|
|
||||||
unsafe {
|
|
||||||
let bytes: [u8; 8] = transmute(n.to_le());
|
|
||||||
copy_nonoverlapping(bytes.as_ptr(), buf.as_mut_ptr(), nbytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
extern crate quickcheck;
|
|
||||||
extern crate rand;
|
|
||||||
|
|
||||||
use test::rand::thread_rng;
|
|
||||||
use test::quickcheck::{QuickCheck, StdGen, Testable};
|
|
||||||
|
|
||||||
const U64_MAX: u64 = ::std::u64::MAX;
|
|
||||||
const I64_MAX: u64 = ::std::i64::MAX as u64;
|
|
||||||
|
|
||||||
fn qc_sized<A: Testable>(f: A, size: u64) {
|
|
||||||
QuickCheck::new()
|
|
||||||
.gen(StdGen::new(thread_rng(), size as usize))
|
|
||||||
.tests(1_00)
|
|
||||||
.max_tests(10_000)
|
|
||||||
.quickcheck(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! qc_byte_order {
|
|
||||||
($name:ident, $ty_int:ident, $max:expr,
|
|
||||||
$bytes:expr, $read:ident, $write:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
|
|
||||||
use super::qc_sized;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn big_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
BigEndian::$write(&mut buf, n, $bytes);
|
|
||||||
n == BigEndian::$read(&mut buf[..$bytes], $bytes)
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn little_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
LittleEndian::$write(&mut buf, n, $bytes);
|
|
||||||
n == LittleEndian::$read(&mut buf[..$bytes], $bytes)
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn native_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
NativeEndian::$write(&mut buf, n, $bytes);
|
|
||||||
n == NativeEndian::$read(&mut buf[..$bytes], $bytes)
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($name:ident, $ty_int:ident, $max:expr,
|
|
||||||
$read:ident, $write:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use std::mem::size_of;
|
|
||||||
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
|
|
||||||
use super::qc_sized;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn big_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let bytes = size_of::<$ty_int>();
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
BigEndian::$write(&mut buf[8 - bytes..], n);
|
|
||||||
n == BigEndian::$read(&mut buf[8 - bytes..])
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn little_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let bytes = size_of::<$ty_int>();
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
LittleEndian::$write(&mut buf[..bytes], n);
|
|
||||||
n == LittleEndian::$read(&mut buf[..bytes])
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn native_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let bytes = size_of::<$ty_int>();
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
NativeEndian::$write(&mut buf[..bytes], n);
|
|
||||||
n == NativeEndian::$read(&mut buf[..bytes])
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
qc_byte_order!(prop_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
|
|
||||||
qc_byte_order!(prop_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
|
|
||||||
qc_byte_order!(prop_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
|
|
||||||
qc_byte_order!(prop_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
|
|
||||||
qc_byte_order!(prop_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
|
|
||||||
qc_byte_order!(prop_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
|
|
||||||
qc_byte_order!(prop_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
|
|
||||||
qc_byte_order!(prop_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
|
|
||||||
|
|
||||||
qc_byte_order!(prop_uint_1, u64, super::U64_MAX, 1, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_2, u64, super::U64_MAX, 2, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_3, u64, super::U64_MAX, 3, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_4, u64, super::U64_MAX, 4, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_5, u64, super::U64_MAX, 5, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_6, u64, super::U64_MAX, 6, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_7, u64, super::U64_MAX, 7, read_uint, write_uint);
|
|
||||||
qc_byte_order!(prop_uint_8, u64, super::U64_MAX, 8, read_uint, write_uint);
|
|
||||||
|
|
||||||
qc_byte_order!(prop_int_1, i64, super::I64_MAX, 1, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_2, i64, super::I64_MAX, 2, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_3, i64, super::I64_MAX, 3, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_4, i64, super::I64_MAX, 4, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_5, i64, super::I64_MAX, 5, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_6, i64, super::I64_MAX, 6, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_7, i64, super::I64_MAX, 7, read_int, write_int);
|
|
||||||
qc_byte_order!(prop_int_8, i64, super::I64_MAX, 8, read_int, write_int);
|
|
||||||
|
|
||||||
macro_rules! qc_bytes_ext {
|
|
||||||
($name:ident, $ty_int:ident, $max:expr,
|
|
||||||
$bytes:expr, $read:ident, $write:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use std::io::Cursor;
|
|
||||||
use {
|
|
||||||
ReadBytesExt, WriteBytesExt,
|
|
||||||
BigEndian, NativeEndian, LittleEndian,
|
|
||||||
};
|
|
||||||
use super::qc_sized;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn big_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<BigEndian>(n).unwrap();
|
|
||||||
let mut rdr = Vec::new();
|
|
||||||
rdr.extend(wtr[8 - $bytes..].iter().map(|&x|x));
|
|
||||||
let mut rdr = Cursor::new(rdr);
|
|
||||||
n == rdr.$read::<BigEndian>($bytes).unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn little_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<LittleEndian>(n).unwrap();
|
|
||||||
let mut rdr = Cursor::new(wtr);
|
|
||||||
n == rdr.$read::<LittleEndian>($bytes).unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn native_endian() {
|
|
||||||
let max = ($max - 1) >> (8 * (8 - $bytes));
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<NativeEndian>(n).unwrap();
|
|
||||||
let mut rdr = Cursor::new(wtr);
|
|
||||||
n == rdr.$read::<NativeEndian>($bytes).unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, max);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($name:ident, $ty_int:ident, $max:expr, $read:ident, $write:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use std::io::Cursor;
|
|
||||||
use {
|
|
||||||
ReadBytesExt, WriteBytesExt,
|
|
||||||
BigEndian, NativeEndian, LittleEndian,
|
|
||||||
};
|
|
||||||
use super::qc_sized;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn big_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<BigEndian>(n).unwrap();
|
|
||||||
let mut rdr = Cursor::new(wtr);
|
|
||||||
n == rdr.$read::<BigEndian>().unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn little_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<LittleEndian>(n).unwrap();
|
|
||||||
let mut rdr = Cursor::new(wtr);
|
|
||||||
n == rdr.$read::<LittleEndian>().unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn native_endian() {
|
|
||||||
fn prop(n: $ty_int) -> bool {
|
|
||||||
let mut wtr = vec![];
|
|
||||||
wtr.$write::<NativeEndian>(n).unwrap();
|
|
||||||
let mut rdr = Cursor::new(wtr);
|
|
||||||
n == rdr.$read::<NativeEndian>().unwrap()
|
|
||||||
}
|
|
||||||
qc_sized(prop as fn($ty_int) -> bool, $max - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
qc_bytes_ext!(prop_ext_u16, u16, ::std::u16::MAX as u64, read_u16, write_u16);
|
|
||||||
qc_bytes_ext!(prop_ext_i16, i16, ::std::i16::MAX as u64, read_i16, write_i16);
|
|
||||||
qc_bytes_ext!(prop_ext_u32, u32, ::std::u32::MAX as u64, read_u32, write_u32);
|
|
||||||
qc_bytes_ext!(prop_ext_i32, i32, ::std::i32::MAX as u64, read_i32, write_i32);
|
|
||||||
qc_bytes_ext!(prop_ext_u64, u64, ::std::u64::MAX as u64, read_u64, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_i64, i64, ::std::i64::MAX as u64, read_i64, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_f32, f32, ::std::u64::MAX as u64, read_f32, write_f32);
|
|
||||||
qc_bytes_ext!(prop_ext_f64, f64, ::std::i64::MAX as u64, read_f64, write_f64);
|
|
||||||
|
|
||||||
qc_bytes_ext!(prop_ext_uint_1, u64, super::U64_MAX, 1, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_2, u64, super::U64_MAX, 2, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_3, u64, super::U64_MAX, 3, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_4, u64, super::U64_MAX, 4, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_5, u64, super::U64_MAX, 5, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_6, u64, super::U64_MAX, 6, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_7, u64, super::U64_MAX, 7, read_uint, write_u64);
|
|
||||||
qc_bytes_ext!(prop_ext_uint_8, u64, super::U64_MAX, 8, read_uint, write_u64);
|
|
||||||
|
|
||||||
qc_bytes_ext!(prop_ext_int_1, i64, super::I64_MAX, 1, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_2, i64, super::I64_MAX, 2, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_3, i64, super::I64_MAX, 3, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_4, i64, super::I64_MAX, 4, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_5, i64, super::I64_MAX, 5, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_6, i64, super::I64_MAX, 6, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_7, i64, super::I64_MAX, 7, read_int, write_i64);
|
|
||||||
qc_bytes_ext!(prop_ext_int_8, i64, super::I64_MAX, 8, read_int, write_i64);
|
|
||||||
|
|
||||||
// Test that all of the byte conversion functions panic when given a
|
|
||||||
// buffer that is too small.
|
|
||||||
//
|
|
||||||
// These tests are critical to ensure safety, otherwise we might end up
|
|
||||||
// with a buffer overflow.
|
|
||||||
macro_rules! too_small {
|
|
||||||
($name:ident, $maximally_small:expr, $zero:expr,
|
|
||||||
$read:ident, $write:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_big_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
BigEndian::$read(&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_little_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
LittleEndian::$read(&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_native_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
NativeEndian::$read(&buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn write_big_endian() {
|
|
||||||
let mut buf = [0; $maximally_small];
|
|
||||||
BigEndian::$write(&mut buf, $zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn write_little_endian() {
|
|
||||||
let mut buf = [0; $maximally_small];
|
|
||||||
LittleEndian::$write(&mut buf, $zero);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn write_native_endian() {
|
|
||||||
let mut buf = [0; $maximally_small];
|
|
||||||
NativeEndian::$write(&mut buf, $zero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
($name:ident, $maximally_small:expr, $read:ident) => (
|
|
||||||
mod $name {
|
|
||||||
use {BigEndian, ByteOrder, NativeEndian, LittleEndian};
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_big_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
BigEndian::$read(&buf, $maximally_small + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_little_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
LittleEndian::$read(&buf, $maximally_small + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[should_panic]
|
|
||||||
fn read_native_endian() {
|
|
||||||
let buf = [0; $maximally_small];
|
|
||||||
NativeEndian::$read(&buf, $maximally_small + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
too_small!(small_u16, 1, 0, read_u16, write_u16);
|
|
||||||
too_small!(small_i16, 1, 0, read_i16, write_i16);
|
|
||||||
too_small!(small_u32, 3, 0, read_u32, write_u32);
|
|
||||||
too_small!(small_i32, 3, 0, read_i32, write_i32);
|
|
||||||
too_small!(small_u64, 7, 0, read_u64, write_u64);
|
|
||||||
too_small!(small_i64, 7, 0, read_i64, write_i64);
|
|
||||||
too_small!(small_f32, 3, 0.0, read_f32, write_f32);
|
|
||||||
too_small!(small_f64, 7, 0.0, read_f64, write_f64);
|
|
||||||
|
|
||||||
too_small!(small_uint_1, 1, read_uint);
|
|
||||||
too_small!(small_uint_2, 2, read_uint);
|
|
||||||
too_small!(small_uint_3, 3, read_uint);
|
|
||||||
too_small!(small_uint_4, 4, read_uint);
|
|
||||||
too_small!(small_uint_5, 5, read_uint);
|
|
||||||
too_small!(small_uint_6, 6, read_uint);
|
|
||||||
too_small!(small_uint_7, 7, read_uint);
|
|
||||||
|
|
||||||
too_small!(small_int_1, 1, read_int);
|
|
||||||
too_small!(small_int_2, 2, read_int);
|
|
||||||
too_small!(small_int_3, 3, read_int);
|
|
||||||
too_small!(small_int_4, 4, read_int);
|
|
||||||
too_small!(small_int_5, 5, read_int);
|
|
||||||
too_small!(small_int_6, 6, read_int);
|
|
||||||
too_small!(small_int_7, 7, read_int);
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn uint_bigger_buffer() {
|
|
||||||
use {ByteOrder, LittleEndian};
|
|
||||||
let n = LittleEndian::read_uint(&[1, 2, 3, 4, 5, 6, 7, 8], 5);
|
|
||||||
assert_eq!(n, 0x0504030201);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
269
third_party/rust/byteorder/src/new.rs
vendored
269
third_party/rust/byteorder/src/new.rs
vendored
|
|
@ -1,269 +0,0 @@
|
||||||
use std::io::{self, Result};
|
|
||||||
|
|
||||||
use ByteOrder;
|
|
||||||
|
|
||||||
/// Extends `Read` with methods for reading numbers. (For `std::io`.)
|
|
||||||
///
|
|
||||||
/// Most of the methods defined here have an unconstrained type parameter that
|
|
||||||
/// must be explicitly instantiated. Typically, it is instantiated with either
|
|
||||||
/// the `BigEndian` or `LittleEndian` types defined in this crate.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Read unsigned 16 bit big-endian integers from a `Read`:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use std::io::Cursor;
|
|
||||||
/// use byteorder::{BigEndian, ReadBytesExt};
|
|
||||||
///
|
|
||||||
/// let mut rdr = Cursor::new(vec![2, 5, 3, 0]);
|
|
||||||
/// assert_eq!(517, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
/// assert_eq!(768, rdr.read_u16::<BigEndian>().unwrap());
|
|
||||||
/// ```
|
|
||||||
pub trait ReadBytesExt: io::Read {
|
|
||||||
/// Reads an unsigned 8 bit integer from the underlying reader.
|
|
||||||
///
|
|
||||||
/// Note that since this reads a single byte, no byte order conversions
|
|
||||||
/// are used. It is included for completeness.
|
|
||||||
#[inline]
|
|
||||||
fn read_u8(&mut self) -> Result<u8> {
|
|
||||||
let mut buf = [0; 1];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(buf[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 8 bit integer from the underlying reader.
|
|
||||||
///
|
|
||||||
/// Note that since this reads a single byte, no byte order conversions
|
|
||||||
/// are used. It is included for completeness.
|
|
||||||
#[inline]
|
|
||||||
fn read_i8(&mut self) -> Result<i8> {
|
|
||||||
let mut buf = [0; 1];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(buf[0] as i8)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an unsigned 16 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_u16<T: ByteOrder>(&mut self) -> Result<u16> {
|
|
||||||
let mut buf = [0; 2];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_u16(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 16 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_i16<T: ByteOrder>(&mut self) -> Result<i16> {
|
|
||||||
let mut buf = [0; 2];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_i16(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an unsigned 32 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_u32<T: ByteOrder>(&mut self) -> Result<u32> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_u32(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 32 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_i32<T: ByteOrder>(&mut self) -> Result<i32> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_i32(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an unsigned 64 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_u64<T: ByteOrder>(&mut self) -> Result<u64> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_u64(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed 64 bit integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_i64<T: ByteOrder>(&mut self) -> Result<i64> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_i64(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads an unsigned n-bytes integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_uint<T: ByteOrder>(&mut self, nbytes: usize) -> Result<u64> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
try!(self.read_exact(&mut buf[..nbytes]));
|
|
||||||
Ok(T::read_uint(&buf[..nbytes], nbytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a signed n-bytes integer from the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_int<T: ByteOrder>(&mut self, nbytes: usize) -> Result<i64> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
try!(self.read_exact(&mut buf[..nbytes]));
|
|
||||||
Ok(T::read_int(&buf[..nbytes], nbytes))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a IEEE754 single-precision (4 bytes) floating point number from
|
|
||||||
/// the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_f32<T: ByteOrder>(&mut self) -> Result<f32> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_f32(&buf))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads a IEEE754 double-precision (8 bytes) floating point number from
|
|
||||||
/// the underlying reader.
|
|
||||||
#[inline]
|
|
||||||
fn read_f64<T: ByteOrder>(&mut self) -> Result<f64> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
try!(self.read_exact(&mut buf));
|
|
||||||
Ok(T::read_f64(&buf))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// All types that implement `Read` get methods defined in `ReadBytesExt`
|
|
||||||
/// for free.
|
|
||||||
impl<R: io::Read + ?Sized> ReadBytesExt for R {}
|
|
||||||
|
|
||||||
/// Extends `Write` with methods for writing numbers. (For `std::io`.)
|
|
||||||
///
|
|
||||||
/// Most of the methods defined here have an unconstrained type parameter that
|
|
||||||
/// must be explicitly instantiated. Typically, it is instantiated with either
|
|
||||||
/// the `BigEndian` or `LittleEndian` types defined in this crate.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// Write unsigned 16 bit big-endian integers to a `Write`:
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// use byteorder::{BigEndian, WriteBytesExt};
|
|
||||||
///
|
|
||||||
/// let mut wtr = vec![];
|
|
||||||
/// wtr.write_u16::<BigEndian>(517).unwrap();
|
|
||||||
/// wtr.write_u16::<BigEndian>(768).unwrap();
|
|
||||||
/// assert_eq!(wtr, vec![2, 5, 3, 0]);
|
|
||||||
/// ```
|
|
||||||
pub trait WriteBytesExt: io::Write {
|
|
||||||
/// Writes an unsigned 8 bit integer to the underlying writer.
|
|
||||||
///
|
|
||||||
/// Note that since this writes a single byte, no byte order conversions
|
|
||||||
/// are used. It is included for completeness.
|
|
||||||
#[inline]
|
|
||||||
fn write_u8(&mut self, n: u8) -> Result<()> {
|
|
||||||
self.write_all(&[n])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 8 bit integer to the underlying writer.
|
|
||||||
///
|
|
||||||
/// Note that since this writes a single byte, no byte order conversions
|
|
||||||
/// are used. It is included for completeness.
|
|
||||||
#[inline]
|
|
||||||
fn write_i8(&mut self, n: i8) -> Result<()> {
|
|
||||||
self.write_all(&[n as u8])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned 16 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_u16<T: ByteOrder>(&mut self, n: u16) -> Result<()> {
|
|
||||||
let mut buf = [0; 2];
|
|
||||||
T::write_u16(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 16 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_i16<T: ByteOrder>(&mut self, n: i16) -> Result<()> {
|
|
||||||
let mut buf = [0; 2];
|
|
||||||
T::write_i16(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned 32 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_u32<T: ByteOrder>(&mut self, n: u32) -> Result<()> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
T::write_u32(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 32 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_i32<T: ByteOrder>(&mut self, n: i32) -> Result<()> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
T::write_i32(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned 64 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_u64<T: ByteOrder>(&mut self, n: u64) -> Result<()> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
T::write_u64(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed 64 bit integer to the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_i64<T: ByteOrder>(&mut self, n: i64) -> Result<()> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
T::write_i64(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes an unsigned n-bytes integer to the underlying writer.
|
|
||||||
///
|
|
||||||
/// If the given integer is not representable in the given number of bytes,
|
|
||||||
/// this method panics. If `nbytes > 8`, this method panics.
|
|
||||||
#[inline]
|
|
||||||
fn write_uint<T: ByteOrder>(
|
|
||||||
&mut self,
|
|
||||||
n: u64,
|
|
||||||
nbytes: usize,
|
|
||||||
) -> Result<()> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
T::write_uint(&mut buf, n, nbytes);
|
|
||||||
self.write_all(&buf[0..nbytes])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a signed n-bytes integer to the underlying writer.
|
|
||||||
///
|
|
||||||
/// If the given integer is not representable in the given number of bytes,
|
|
||||||
/// this method panics. If `nbytes > 8`, this method panics.
|
|
||||||
#[inline]
|
|
||||||
fn write_int<T: ByteOrder>(
|
|
||||||
&mut self,
|
|
||||||
n: i64,
|
|
||||||
nbytes: usize,
|
|
||||||
) -> Result<()> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
T::write_int(&mut buf, n, nbytes);
|
|
||||||
self.write_all(&buf[0..nbytes])
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a IEEE754 single-precision (4 bytes) floating point number to
|
|
||||||
/// the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_f32<T: ByteOrder>(&mut self, n: f32) -> Result<()> {
|
|
||||||
let mut buf = [0; 4];
|
|
||||||
T::write_f32(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes a IEEE754 double-precision (8 bytes) floating point number to
|
|
||||||
/// the underlying writer.
|
|
||||||
#[inline]
|
|
||||||
fn write_f64<T: ByteOrder>(&mut self, n: f64) -> Result<()> {
|
|
||||||
let mut buf = [0; 8];
|
|
||||||
T::write_f64(&mut buf, n);
|
|
||||||
self.write_all(&buf)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// All types that implement `Write` get methods defined in `WriteBytesExt`
|
|
||||||
/// for free.
|
|
||||||
impl<W: io::Write + ?Sized> WriteBytesExt for W {}
|
|
||||||
1
third_party/rust/gcc/.cargo-checksum.json
vendored
1
third_party/rust/gcc/.cargo-checksum.json
vendored
|
|
@ -1 +0,0 @@
|
||||||
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"f9b1ca6ae27d1c18215265024629a8960c31379f206d9ed20f64e0b2dcf79805",".travis.yml":"5cee7774cf6d876246a0ae0f8362cceeecec5924b751049c945faac9342565ff","Cargo.toml":"2f9146c71ba5dee801cc2e4c527902408c221b10ef67cd48c5d13802447d7557","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ecb2d93f4c81edbd48d8742ff7887dc0a4530a5890967839090bbc972d49bebe","appveyor.yml":"0ae8475d1be56af48cbb6a7bf774c6167c88ddaea96f2eca4f4c190dd6dab5e4","src/bin/gcc-shim.rs":"11edfe1fc6f932bd42ffffda5145833302bc163e0b87dc0d54f4bd0997ad4708","src/lib.rs":"a62a24a2703d744f5a6308d48c20938ca08fe246395a6bd6a76dd33ee3729654","src/registry.rs":"3e2a42581ebb82e325dd5600c6571cef937b35003b2927dc618967f5238a2058","src/windows_registry.rs":"80b1556b1a94ae46b444268f8e74b9ac4ddd7e6d2b98eca8ae643a8bd099abe1","tests/cc_env.rs":"d92c5e3d3d43ac244e63b2cd2c93a521fcf124bf1ccf8d4c6bfa7f8333d88976","tests/support/mod.rs":"d11ed0db4dda5ecf5fb970c9b0c56428cd47421a2742f07032e2cc6b0a0f07e2","tests/test.rs":"4ef5c34f6d8954e64c97c2876e2697dad5efc7e1dacef4b567931ed3970425c6"},"package":"91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312"}
|
|
||||||
0
third_party/rust/gcc/.cargo-ok
vendored
0
third_party/rust/gcc/.cargo-ok
vendored
2
third_party/rust/gcc/.gitignore
vendored
2
third_party/rust/gcc/.gitignore
vendored
|
|
@ -1,2 +0,0 @@
|
||||||
target
|
|
||||||
Cargo.lock
|
|
||||||
40
third_party/rust/gcc/.travis.yml
vendored
40
third_party/rust/gcc/.travis.yml
vendored
|
|
@ -1,40 +0,0 @@
|
||||||
language: rust
|
|
||||||
rust:
|
|
||||||
- stable
|
|
||||||
- beta
|
|
||||||
- nightly
|
|
||||||
sudo: false
|
|
||||||
install:
|
|
||||||
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then OS=unknown-linux-gnu; else OS=apple-darwin; fi
|
|
||||||
- export TARGET=$ARCH-$OS
|
|
||||||
- curl https://static.rust-lang.org/rustup.sh |
|
|
||||||
sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot`
|
|
||||||
before_script:
|
|
||||||
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
|
|
||||||
script:
|
|
||||||
- cargo build --verbose
|
|
||||||
- cargo test --verbose
|
|
||||||
- cargo test --verbose --features parallel
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --features parallel
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml --target $TARGET --release
|
|
||||||
- cargo doc
|
|
||||||
- rustdoc --test README.md -L target/debug -L target/debug/deps
|
|
||||||
after_success:
|
|
||||||
- travis-cargo --only nightly doc-upload
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
secure: ilbcq9zX+UaiBcwqkBGldeanbEQus9npLsi0/nF1PUxKbQsoWSVtVOehAD8Hy92D3hX2npIRyNL8GxBn85XEcBYc1h7DiWUhLcXfZie79v8Ly/qboHCfZLXlB1ofbypbyQfouEdOE9zHf0ZILYVpAgUkliv6KuVShsrKNlbn4QE=
|
|
||||||
matrix:
|
|
||||||
- ARCH=x86_64
|
|
||||||
- ARCH=i686
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
addons:
|
|
||||||
apt:
|
|
||||||
packages:
|
|
||||||
- g++-multilib
|
|
||||||
23
third_party/rust/gcc/Cargo.toml
vendored
23
third_party/rust/gcc/Cargo.toml
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
[package]
|
|
||||||
|
|
||||||
name = "gcc"
|
|
||||||
version = "0.3.35"
|
|
||||||
authors = ["Alex Crichton <alex@alexcrichton.com>"]
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
repository = "https://github.com/alexcrichton/gcc-rs"
|
|
||||||
documentation = "http://alexcrichton.com/gcc-rs"
|
|
||||||
description = """
|
|
||||||
A build-time dependency for Cargo build scripts to assist in invoking the native
|
|
||||||
C compiler to compile native C code into a static archive to be linked into Rust
|
|
||||||
code.
|
|
||||||
"""
|
|
||||||
keywords = ["build-dependencies"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
rayon = { version = "0.4", optional = true }
|
|
||||||
|
|
||||||
[features]
|
|
||||||
parallel = ["rayon"]
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tempdir = "0.3"
|
|
||||||
201
third_party/rust/gcc/LICENSE-APACHE
vendored
201
third_party/rust/gcc/LICENSE-APACHE
vendored
|
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
25
third_party/rust/gcc/LICENSE-MIT
vendored
25
third_party/rust/gcc/LICENSE-MIT
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
Copyright (c) 2014 Alex Crichton
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any
|
|
||||||
person obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without
|
|
||||||
limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software
|
|
||||||
is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice
|
|
||||||
shall be included in all copies or substantial portions
|
|
||||||
of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
||||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
||||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
161
third_party/rust/gcc/README.md
vendored
161
third_party/rust/gcc/README.md
vendored
|
|
@ -1,161 +0,0 @@
|
||||||
# gcc-rs
|
|
||||||
|
|
||||||
A library to compile C/C++ code into a Rust library/application.
|
|
||||||
|
|
||||||
[](https://travis-ci.org/alexcrichton/gcc-rs)
|
|
||||||
[](https://ci.appveyor.com/project/alexcrichton/gcc-rs)
|
|
||||||
|
|
||||||
[Documentation](http://alexcrichton.com/gcc-rs)
|
|
||||||
|
|
||||||
A simple library meant to be used as a build dependency with Cargo packages in
|
|
||||||
order to build a set of C/C++ files into a static archive. Note that while this
|
|
||||||
crate is called "gcc", it actually calls out to the most relevant compile for
|
|
||||||
a platform, for example using `cl` on MSVC. That is, this crate does indeed work
|
|
||||||
on MSVC!
|
|
||||||
|
|
||||||
## Using gcc-rs
|
|
||||||
|
|
||||||
First, you'll want to both add a build script for your crate (`build.rs`) and
|
|
||||||
also add this crate to your `Cargo.toml` via:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[package]
|
|
||||||
# ...
|
|
||||||
build = "build.rs"
|
|
||||||
|
|
||||||
[build-dependencies]
|
|
||||||
gcc = "0.3"
|
|
||||||
```
|
|
||||||
|
|
||||||
Next up, you'll want to write a build script like so:
|
|
||||||
|
|
||||||
```rust,no_run
|
|
||||||
// build.rs
|
|
||||||
|
|
||||||
extern crate gcc;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]);
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
And that's it! Running `cargo build` should take care of the rest and your Rust
|
|
||||||
application will now have the C files `foo.c` and `bar.c` compiled into it. You
|
|
||||||
can call the functions in Rust by declaring functions in your Rust code like so:
|
|
||||||
|
|
||||||
```
|
|
||||||
extern {
|
|
||||||
fn foo_function();
|
|
||||||
fn bar_function();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn call() {
|
|
||||||
unsafe {
|
|
||||||
foo_function();
|
|
||||||
bar_function();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// ...
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## External configuration via environment variables
|
|
||||||
|
|
||||||
To control the programs and flags used for building, the builder can set a
|
|
||||||
number of different environment variables.
|
|
||||||
|
|
||||||
* `CFLAGS` - a series of space separated flags passed to "gcc". Note that
|
|
||||||
individual flags cannot currently contain spaces, so doing
|
|
||||||
something like: "-L=foo\ bar" is not possible.
|
|
||||||
* `CC` - the actual C compiler used. Note that this is used as an exact
|
|
||||||
executable name, so (for example) no extra flags can be passed inside
|
|
||||||
this variable, and the builder must ensure that there aren't any
|
|
||||||
trailing spaces. This compiler must understand the `-c` flag. For
|
|
||||||
certain `TARGET`s, it also is assumed to know about other flags (most
|
|
||||||
common is `-fPIC`).
|
|
||||||
* `AR` - the `ar` (archiver) executable to use to build the static library.
|
|
||||||
|
|
||||||
Each of these variables can also be supplied with certain prefixes and suffixes,
|
|
||||||
in the following prioritized order:
|
|
||||||
|
|
||||||
1. `<var>_<target>` - for example, `CC_x86_64-unknown-linux-gnu`
|
|
||||||
2. `<var>_<target_with_underscores>` - for example, `CC_x86_64_unknown_linux_gnu`
|
|
||||||
3. `<build-kind>_<var>` - for example, `HOST_CC` or `TARGET_CFLAGS`
|
|
||||||
4. `<var>` - a plain `CC`, `AR` as above.
|
|
||||||
|
|
||||||
If none of these variables exist, gcc-rs uses built-in defaults
|
|
||||||
|
|
||||||
In addition to the the above optional environment variables, `gcc-rs` has some
|
|
||||||
functions with hard requirements on some variables supplied by [cargo's
|
|
||||||
build-script driver][cargo] that it has the `TARGET`, `OUT_DIR`, `OPT_LEVEL`,
|
|
||||||
and `HOST` variables.
|
|
||||||
|
|
||||||
[cargo]: http://doc.crates.io/build-script.html#inputs-to-the-build-script
|
|
||||||
|
|
||||||
## Optional features
|
|
||||||
|
|
||||||
Currently gcc-rs supports parallel compilation (think `make -jN`) but this
|
|
||||||
feature is turned off by default. To enable gcc-rs to compile C/C++ in parallel,
|
|
||||||
you can change your dependency to:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[build-dependencies]
|
|
||||||
gcc = { version = "0.3", features = ["parallel"] }
|
|
||||||
```
|
|
||||||
|
|
||||||
By default gcc-rs will limit parallelism to `$NUM_JOBS`, or if not present it
|
|
||||||
will limit it to the number of cpus on the machine.
|
|
||||||
|
|
||||||
## Compile-time Requirements
|
|
||||||
|
|
||||||
To work properly this crate needs access to a C compiler when the build script
|
|
||||||
is being run. This crate does not ship a C compiler with it. The compiler
|
|
||||||
required varies per platform, but there are three broad categories:
|
|
||||||
|
|
||||||
* Unix platforms require `cc` to be the C compiler. This can be found by
|
|
||||||
installing gcc/clang on Linux distributions and Xcode on OSX, for example.
|
|
||||||
* Windows platforms targeting MSVC (e.g. your target triple ends in `-msvc`)
|
|
||||||
require `cl.exe` to be available and in `PATH`. This is typically found in
|
|
||||||
standard Visual Studio installations and the `PATH` can be set up by running
|
|
||||||
the appropriate developer tools shell.
|
|
||||||
* Windows platforms targeting MinGW (e.g. your target triple ends in `-gnu`)
|
|
||||||
require `gcc` to be available in `PATH`. We recommend the
|
|
||||||
[MinGW-w64](http://mingw-w64.org) distribution, which is using the
|
|
||||||
[Win-builds](http://win-builds.org) installation system.
|
|
||||||
You may also acquire it via
|
|
||||||
[MSYS2](http://msys2.github.io), as explained [here][msys2-help]. Make sure
|
|
||||||
to install the appropriate architecture corresponding to your installation of
|
|
||||||
rustc. GCC from older [MinGW](http://www.mingw.org) project is compatible
|
|
||||||
only with 32-bit rust compiler.
|
|
||||||
|
|
||||||
[msys2-help]: http://github.com/rust-lang/rust#building-on-windows
|
|
||||||
|
|
||||||
## C++ support
|
|
||||||
|
|
||||||
`gcc-rs` supports C++ libraries compilation by using the `cpp` method on
|
|
||||||
`Config`:
|
|
||||||
|
|
||||||
```rust,no_run
|
|
||||||
extern crate gcc;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
gcc::Config::new()
|
|
||||||
.cpp(true) // Switch to C++ library compilation.
|
|
||||||
.file("foo.cpp")
|
|
||||||
.compile("libfoo.a");
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When using C++ library compilation switch, the `CXX` and `CXXFLAGS` env
|
|
||||||
variables are used instead of `CC` and `CFLAGS` and the C++ standard library is
|
|
||||||
linked to the crate target.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
`gcc-rs` is primarily distributed under the terms of both the MIT license and
|
|
||||||
the Apache License (Version 2.0), with portions covered by various BSD-like
|
|
||||||
licenses.
|
|
||||||
|
|
||||||
See LICENSE-APACHE, and LICENSE-MIT for details.
|
|
||||||
35
third_party/rust/gcc/appveyor.yml
vendored
35
third_party/rust/gcc/appveyor.yml
vendored
|
|
@ -1,35 +0,0 @@
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
|
||||||
ARCH: amd64
|
|
||||||
VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
|
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
|
||||||
ARCH: amd64
|
|
||||||
VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
|
||||||
- TARGET: i686-pc-windows-msvc
|
|
||||||
ARCH: x86
|
|
||||||
VS: C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat
|
|
||||||
- TARGET: i686-pc-windows-msvc
|
|
||||||
ARCH: x86
|
|
||||||
VS: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat
|
|
||||||
- TARGET: x86_64-pc-windows-gnu
|
|
||||||
MSYS_BITS: 64
|
|
||||||
- TARGET: i686-pc-windows-gnu
|
|
||||||
MSYS_BITS: 32
|
|
||||||
install:
|
|
||||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-nightly-${env:TARGET}.exe"
|
|
||||||
- rust-nightly-%TARGET%.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
|
||||||
- if defined VS call "%VS%" %ARCH%
|
|
||||||
- set PATH=%PATH%;C:\Program Files (x86)\Rust\bin
|
|
||||||
- if defined MSYS_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS_BITS%\bin
|
|
||||||
- rustc -V
|
|
||||||
- cargo -V
|
|
||||||
|
|
||||||
build: false
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- cargo test
|
|
||||||
- cargo test --features parallel
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml --features parallel
|
|
||||||
- cargo test --manifest-path gcc-test/Cargo.toml --release
|
|
||||||
23
third_party/rust/gcc/src/bin/gcc-shim.rs
vendored
23
third_party/rust/gcc/src/bin/gcc-shim.rs
vendored
|
|
@ -1,23 +0,0 @@
|
||||||
#![cfg_attr(test, allow(dead_code))]
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let out_dir = PathBuf::from(env::var_os("GCCTEST_OUT_DIR").unwrap());
|
|
||||||
for i in 0.. {
|
|
||||||
let candidate = out_dir.join(format!("out{}", i));
|
|
||||||
if candidate.exists() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
let mut f = File::create(candidate).unwrap();
|
|
||||||
for arg in env::args().skip(1) {
|
|
||||||
writeln!(f, "{}", arg).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
File::create(out_dir.join("libfoo.a")).unwrap();
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
898
third_party/rust/gcc/src/lib.rs
vendored
898
third_party/rust/gcc/src/lib.rs
vendored
|
|
@ -1,898 +0,0 @@
|
||||||
//! A library for build scripts to compile custom C code
|
|
||||||
//!
|
|
||||||
//! This library is intended to be used as a `build-dependencies` entry in
|
|
||||||
//! `Cargo.toml`:
|
|
||||||
//!
|
|
||||||
//! ```toml
|
|
||||||
//! [build-dependencies]
|
|
||||||
//! gcc = "0.3"
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! The purpose of this crate is to provide the utility functions necessary to
|
|
||||||
//! compile C code into a static archive which is then linked into a Rust crate.
|
|
||||||
//! The top-level `compile_library` function serves as a convenience and more
|
|
||||||
//! advanced configuration is available through the `Config` builder.
|
|
||||||
//!
|
|
||||||
//! This crate will automatically detect situations such as cross compilation or
|
|
||||||
//! other environment variables set by Cargo and will build code appropriately.
|
|
||||||
//!
|
|
||||||
//! # Examples
|
|
||||||
//!
|
|
||||||
//! Use the default configuration:
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! extern crate gcc;
|
|
||||||
//!
|
|
||||||
//! fn main() {
|
|
||||||
//! gcc::compile_library("libfoo.a", &["src/foo.c"]);
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Use more advanced configuration:
|
|
||||||
//!
|
|
||||||
//! ```no_run
|
|
||||||
//! extern crate gcc;
|
|
||||||
//!
|
|
||||||
//! fn main() {
|
|
||||||
//! gcc::Config::new()
|
|
||||||
//! .file("src/foo.c")
|
|
||||||
//! .define("FOO", Some("bar"))
|
|
||||||
//! .include("src")
|
|
||||||
//! .compile("libfoo.a");
|
|
||||||
//! }
|
|
||||||
//! ```
|
|
||||||
|
|
||||||
#![doc(html_root_url = "http://alexcrichton.com/gcc-rs")]
|
|
||||||
#![cfg_attr(test, deny(warnings))]
|
|
||||||
#![deny(missing_docs)]
|
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
|
||||||
extern crate rayon;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::ffi::{OsString, OsStr};
|
|
||||||
use std::fs;
|
|
||||||
use std::io;
|
|
||||||
use std::path::{PathBuf, Path};
|
|
||||||
use std::process::{Command, Stdio};
|
|
||||||
use std::io::{BufReader, BufRead, Write};
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
mod registry;
|
|
||||||
pub mod windows_registry;
|
|
||||||
|
|
||||||
/// Extra configuration to pass to gcc.
|
|
||||||
pub struct Config {
|
|
||||||
include_directories: Vec<PathBuf>,
|
|
||||||
definitions: Vec<(String, Option<String>)>,
|
|
||||||
objects: Vec<PathBuf>,
|
|
||||||
flags: Vec<String>,
|
|
||||||
files: Vec<PathBuf>,
|
|
||||||
cpp: bool,
|
|
||||||
cpp_link_stdlib: Option<Option<String>>,
|
|
||||||
cpp_set_stdlib: Option<String>,
|
|
||||||
target: Option<String>,
|
|
||||||
host: Option<String>,
|
|
||||||
out_dir: Option<PathBuf>,
|
|
||||||
opt_level: Option<u32>,
|
|
||||||
debug: Option<bool>,
|
|
||||||
env: Vec<(OsString, OsString)>,
|
|
||||||
compiler: Option<PathBuf>,
|
|
||||||
archiver: Option<PathBuf>,
|
|
||||||
cargo_metadata: bool,
|
|
||||||
pic: Option<bool>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configuration used to represent an invocation of a C compiler.
|
|
||||||
///
|
|
||||||
/// This can be used to figure out what compiler is in use, what the arguments
|
|
||||||
/// to it are, and what the environment variables look like for the compiler.
|
|
||||||
/// This can be used to further configure other build systems (e.g. forward
|
|
||||||
/// along CC and/or CFLAGS) or the `to_command` method can be used to run the
|
|
||||||
/// compiler itself.
|
|
||||||
pub struct Tool {
|
|
||||||
path: PathBuf,
|
|
||||||
args: Vec<OsString>,
|
|
||||||
env: Vec<(OsString, OsString)>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Compile a library from the given set of input C files.
|
|
||||||
///
|
|
||||||
/// This will simply compile all files into object files and then assemble them
|
|
||||||
/// into the output. This will read the standard environment variables to detect
|
|
||||||
/// cross compilations and such.
|
|
||||||
///
|
|
||||||
/// This function will also print all metadata on standard output for Cargo.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// gcc::compile_library("libfoo.a", &["foo.c", "bar.c"]);
|
|
||||||
/// ```
|
|
||||||
pub fn compile_library(output: &str, files: &[&str]) {
|
|
||||||
let mut c = Config::new();
|
|
||||||
for f in files.iter() {
|
|
||||||
c.file(*f);
|
|
||||||
}
|
|
||||||
c.compile(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Config {
|
|
||||||
/// Construct a new instance of a blank set of configuration.
|
|
||||||
///
|
|
||||||
/// This builder is finished with the `compile` function.
|
|
||||||
pub fn new() -> Config {
|
|
||||||
Config {
|
|
||||||
include_directories: Vec::new(),
|
|
||||||
definitions: Vec::new(),
|
|
||||||
objects: Vec::new(),
|
|
||||||
flags: Vec::new(),
|
|
||||||
files: Vec::new(),
|
|
||||||
cpp: false,
|
|
||||||
cpp_link_stdlib: None,
|
|
||||||
cpp_set_stdlib: None,
|
|
||||||
target: None,
|
|
||||||
host: None,
|
|
||||||
out_dir: None,
|
|
||||||
opt_level: None,
|
|
||||||
debug: None,
|
|
||||||
env: Vec::new(),
|
|
||||||
compiler: None,
|
|
||||||
archiver: None,
|
|
||||||
cargo_metadata: true,
|
|
||||||
pic: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a directory to the `-I` or include path for headers
|
|
||||||
pub fn include<P: AsRef<Path>>(&mut self, dir: P) -> &mut Config {
|
|
||||||
self.include_directories.push(dir.as_ref().to_path_buf());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Specify a `-D` variable with an optional value.
|
|
||||||
pub fn define(&mut self, var: &str, val: Option<&str>) -> &mut Config {
|
|
||||||
self.definitions.push((var.to_string(), val.map(|s| s.to_string())));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an arbitrary object file to link in
|
|
||||||
pub fn object<P: AsRef<Path>>(&mut self, obj: P) -> &mut Config {
|
|
||||||
self.objects.push(obj.as_ref().to_path_buf());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add an arbitrary flag to the invocation of the compiler
|
|
||||||
pub fn flag(&mut self, flag: &str) -> &mut Config {
|
|
||||||
self.flags.push(flag.to_string());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add a file which will be compiled
|
|
||||||
pub fn file<P: AsRef<Path>>(&mut self, p: P) -> &mut Config {
|
|
||||||
self.files.push(p.as_ref().to_path_buf());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set C++ support.
|
|
||||||
///
|
|
||||||
/// The other `cpp_*` options will only become active if this is set to
|
|
||||||
/// `true`.
|
|
||||||
pub fn cpp(&mut self, cpp: bool) -> &mut Config {
|
|
||||||
self.cpp = cpp;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the standard library to link against when compiling with C++
|
|
||||||
/// support.
|
|
||||||
///
|
|
||||||
/// The default value of this property depends on the current target: On
|
|
||||||
/// OS X `Some("c++")` is used, when compiling for a Visual Studio based
|
|
||||||
/// target `None` is used and for other targets `Some("stdc++")` is used.
|
|
||||||
///
|
|
||||||
/// A value of `None` indicates that no automatic linking should happen,
|
|
||||||
/// otherwise cargo will link against the specified library.
|
|
||||||
///
|
|
||||||
/// The given library name must not contain the `lib` prefix.
|
|
||||||
pub fn cpp_link_stdlib(&mut self, cpp_link_stdlib: Option<&str>)
|
|
||||||
-> &mut Config {
|
|
||||||
self.cpp_link_stdlib = Some(cpp_link_stdlib.map(|s| s.into()));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Force the C++ compiler to use the specified standard library.
|
|
||||||
///
|
|
||||||
/// Setting this option will automatically set `cpp_link_stdlib` to the same
|
|
||||||
/// value.
|
|
||||||
///
|
|
||||||
/// The default value of this option is always `None`.
|
|
||||||
///
|
|
||||||
/// This option has no effect when compiling for a Visual Studio based
|
|
||||||
/// target.
|
|
||||||
///
|
|
||||||
/// This option sets the `-stdlib` flag, which is only supported by some
|
|
||||||
/// compilers (clang, icc) but not by others (gcc). The library will not
|
|
||||||
/// detect which compiler is used, as such it is the responsibility of the
|
|
||||||
/// caller to ensure that this option is only used in conjuction with a
|
|
||||||
/// compiler which supports the `-stdlib` flag.
|
|
||||||
///
|
|
||||||
/// A value of `None` indicates that no specific C++ standard library should
|
|
||||||
/// be used, otherwise `-stdlib` is added to the compile invocation.
|
|
||||||
///
|
|
||||||
/// The given library name must not contain the `lib` prefix.
|
|
||||||
pub fn cpp_set_stdlib(&mut self, cpp_set_stdlib: Option<&str>)
|
|
||||||
-> &mut Config {
|
|
||||||
self.cpp_set_stdlib = cpp_set_stdlib.map(|s| s.into());
|
|
||||||
self.cpp_link_stdlib(cpp_set_stdlib);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the target this configuration will be compiling for.
|
|
||||||
///
|
|
||||||
/// This option is automatically scraped from the `TARGET` environment
|
|
||||||
/// variable by build scripts, so it's not required to call this function.
|
|
||||||
pub fn target(&mut self, target: &str) -> &mut Config {
|
|
||||||
self.target = Some(target.to_string());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the host assumed by this configuration.
|
|
||||||
///
|
|
||||||
/// This option is automatically scraped from the `HOST` environment
|
|
||||||
/// variable by build scripts, so it's not required to call this function.
|
|
||||||
pub fn host(&mut self, host: &str) -> &mut Config {
|
|
||||||
self.host = Some(host.to_string());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the optimization level of the generated object files.
|
|
||||||
///
|
|
||||||
/// This option is automatically scraped from the `OPT_LEVEL` environment
|
|
||||||
/// variable by build scripts, so it's not required to call this function.
|
|
||||||
pub fn opt_level(&mut self, opt_level: u32) -> &mut Config {
|
|
||||||
self.opt_level = Some(opt_level);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures whether the compiler will emit debug information when
|
|
||||||
/// generating object files.
|
|
||||||
///
|
|
||||||
/// This option is automatically scraped from the `PROFILE` environment
|
|
||||||
/// variable by build scripts (only enabled when the profile is "debug"), so
|
|
||||||
/// it's not required to call this function.
|
|
||||||
pub fn debug(&mut self, debug: bool) -> &mut Config {
|
|
||||||
self.debug = Some(debug);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the output directory where all object files and static
|
|
||||||
/// libraries will be located.
|
|
||||||
///
|
|
||||||
/// This option is automatically scraped from the `OUT_DIR` environment
|
|
||||||
/// variable by build scripts, so it's not required to call this function.
|
|
||||||
pub fn out_dir<P: AsRef<Path>>(&mut self, out_dir: P) -> &mut Config {
|
|
||||||
self.out_dir = Some(out_dir.as_ref().to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the compiler to be used to produce output.
|
|
||||||
///
|
|
||||||
/// This option is automatically determined from the target platform or a
|
|
||||||
/// number of environment variables, so it's not required to call this
|
|
||||||
/// function.
|
|
||||||
pub fn compiler<P: AsRef<Path>>(&mut self, compiler: P) -> &mut Config {
|
|
||||||
self.compiler = Some(compiler.as_ref().to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the tool used to assemble archives.
|
|
||||||
///
|
|
||||||
/// This option is automatically determined from the target platform or a
|
|
||||||
/// number of environment variables, so it's not required to call this
|
|
||||||
/// function.
|
|
||||||
pub fn archiver<P: AsRef<Path>>(&mut self, archiver: P) -> &mut Config {
|
|
||||||
self.archiver = Some(archiver.as_ref().to_owned());
|
|
||||||
self
|
|
||||||
}
|
|
||||||
/// Define whether metadata should be emitted for cargo allowing it to
|
|
||||||
/// automatically link the binary. Defaults to `true`.
|
|
||||||
pub fn cargo_metadata(&mut self, cargo_metadata: bool) -> &mut Config {
|
|
||||||
self.cargo_metadata = cargo_metadata;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures whether the compiler will emit position independent code.
|
|
||||||
///
|
|
||||||
/// This option defaults to `false` for `i686` and `windows-gnu` targets and to `true` for all
|
|
||||||
/// other targets.
|
|
||||||
pub fn pic(&mut self, pic: bool) -> &mut Config {
|
|
||||||
self.pic = Some(pic);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn __set_env<A, B>(&mut self, a: A, b: B) -> &mut Config
|
|
||||||
where A: AsRef<OsStr>, B: AsRef<OsStr>
|
|
||||||
{
|
|
||||||
self.env.push((a.as_ref().to_owned(), b.as_ref().to_owned()));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Run the compiler, generating the file `output`
|
|
||||||
///
|
|
||||||
/// The name `output` must begin with `lib` and end with `.a`
|
|
||||||
pub fn compile(&self, output: &str) {
|
|
||||||
assert!(output.starts_with("lib"));
|
|
||||||
assert!(output.ends_with(".a"));
|
|
||||||
let lib_name = &output[3..output.len() - 2];
|
|
||||||
let dst = self.get_out_dir();
|
|
||||||
|
|
||||||
let mut objects = Vec::new();
|
|
||||||
let mut src_dst = Vec::new();
|
|
||||||
for file in self.files.iter() {
|
|
||||||
let obj = dst.join(file).with_extension("o");
|
|
||||||
let obj = if !obj.starts_with(&dst) {
|
|
||||||
dst.join(obj.file_name().unwrap())
|
|
||||||
} else {
|
|
||||||
obj
|
|
||||||
};
|
|
||||||
fs::create_dir_all(&obj.parent().unwrap()).unwrap();
|
|
||||||
src_dst.push((file.to_path_buf(), obj.clone()));
|
|
||||||
objects.push(obj);
|
|
||||||
}
|
|
||||||
self.compile_objects(&src_dst);
|
|
||||||
self.assemble(lib_name, &dst.join(output), &objects);
|
|
||||||
|
|
||||||
self.print(&format!("cargo:rustc-link-lib=static={}",
|
|
||||||
&output[3..output.len() - 2]));
|
|
||||||
self.print(&format!("cargo:rustc-link-search=native={}", dst.display()));
|
|
||||||
|
|
||||||
// Add specific C++ libraries, if enabled.
|
|
||||||
if self.cpp {
|
|
||||||
if let Some(stdlib) = self.get_cpp_link_stdlib() {
|
|
||||||
self.print(&format!("cargo:rustc-link-lib={}", stdlib));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "parallel")]
|
|
||||||
fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) {
|
|
||||||
use self::rayon::prelude::*;
|
|
||||||
|
|
||||||
let mut cfg = rayon::Configuration::new();
|
|
||||||
if let Ok(amt) = env::var("NUM_JOBS") {
|
|
||||||
if let Ok(amt) = amt.parse() {
|
|
||||||
cfg = cfg.set_num_threads(amt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
drop(rayon::initialize(cfg));
|
|
||||||
|
|
||||||
objs.par_iter().weight_max().for_each(|&(ref src, ref dst)| {
|
|
||||||
self.compile_object(src, dst)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "parallel"))]
|
|
||||||
fn compile_objects(&self, objs: &[(PathBuf, PathBuf)]) {
|
|
||||||
for &(ref src, ref dst) in objs {
|
|
||||||
self.compile_object(src, dst);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compile_object(&self, file: &Path, dst: &Path) {
|
|
||||||
let is_asm = file.extension().and_then(|s| s.to_str()) == Some("asm");
|
|
||||||
let msvc = self.get_target().contains("msvc");
|
|
||||||
let (mut cmd, name) = if msvc && is_asm {
|
|
||||||
self.msvc_macro_assembler()
|
|
||||||
} else {
|
|
||||||
let compiler = self.get_compiler();
|
|
||||||
let mut cmd = compiler.to_command();
|
|
||||||
for &(ref a, ref b) in self.env.iter() {
|
|
||||||
cmd.env(a, b);
|
|
||||||
}
|
|
||||||
(cmd, compiler.path.file_name().unwrap()
|
|
||||||
.to_string_lossy().into_owned())
|
|
||||||
};
|
|
||||||
if msvc && is_asm {
|
|
||||||
cmd.arg("/Fo").arg(dst);
|
|
||||||
} else if msvc {
|
|
||||||
let mut s = OsString::from("/Fo");
|
|
||||||
s.push(&dst);
|
|
||||||
cmd.arg(s);
|
|
||||||
} else {
|
|
||||||
cmd.arg("-o").arg(&dst);
|
|
||||||
}
|
|
||||||
cmd.arg(if msvc {"/c"} else {"-c"});
|
|
||||||
cmd.arg(file);
|
|
||||||
|
|
||||||
run(&mut cmd, &name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the compiler that's in use for this configuration.
|
|
||||||
///
|
|
||||||
/// This function will return a `Tool` which represents the culmination
|
|
||||||
/// of this configuration at a snapshot in time. The returned compiler can
|
|
||||||
/// be inspected (e.g. the path, arguments, environment) to forward along to
|
|
||||||
/// other tools, or the `to_command` method can be used to invoke the
|
|
||||||
/// compiler itself.
|
|
||||||
///
|
|
||||||
/// This method will take into account all configuration such as debug
|
|
||||||
/// information, optimization level, include directories, defines, etc.
|
|
||||||
/// Additionally, the compiler binary in use follows the standard
|
|
||||||
/// conventions for this path, e.g. looking at the explicitly set compiler,
|
|
||||||
/// environment variables (a number of which are inspected here), and then
|
|
||||||
/// falling back to the default configuration.
|
|
||||||
pub fn get_compiler(&self) -> Tool {
|
|
||||||
let opt_level = self.get_opt_level();
|
|
||||||
let debug = self.get_debug();
|
|
||||||
let target = self.get_target();
|
|
||||||
let msvc = target.contains("msvc");
|
|
||||||
self.print(&format!("debug={} opt-level={}", debug, opt_level));
|
|
||||||
|
|
||||||
let mut cmd = self.get_base_compiler();
|
|
||||||
let nvcc = cmd.path.to_str()
|
|
||||||
.map(|path| path.contains("nvcc"))
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if msvc {
|
|
||||||
cmd.args.push("/nologo".into());
|
|
||||||
cmd.args.push("/MD".into()); // link against msvcrt.dll for now
|
|
||||||
if opt_level != 0 {
|
|
||||||
cmd.args.push("/O2".into());
|
|
||||||
}
|
|
||||||
if target.contains("i686") {
|
|
||||||
cmd.args.push("/SAFESEH".into());
|
|
||||||
} else if target.contains("i586") {
|
|
||||||
cmd.args.push("/SAFESEH".into());
|
|
||||||
cmd.args.push("/ARCH:IA32".into());
|
|
||||||
}
|
|
||||||
} else if nvcc {
|
|
||||||
cmd.args.push(format!("-O{}", opt_level).into());
|
|
||||||
} else {
|
|
||||||
cmd.args.push(format!("-O{}", opt_level).into());
|
|
||||||
cmd.args.push("-ffunction-sections".into());
|
|
||||||
cmd.args.push("-fdata-sections".into());
|
|
||||||
}
|
|
||||||
for arg in self.envflags(if self.cpp {"CXXFLAGS"} else {"CFLAGS"}) {
|
|
||||||
cmd.args.push(arg.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if debug {
|
|
||||||
cmd.args.push(if msvc {"/Z7"} else {"-g"}.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if target.contains("-ios") {
|
|
||||||
self.ios_flags(&mut cmd);
|
|
||||||
} else if !msvc {
|
|
||||||
if target.contains("i686") || target.contains("i586") {
|
|
||||||
cmd.args.push("-m32".into());
|
|
||||||
} else if target.contains("x86_64") || target.contains("powerpc64") {
|
|
||||||
cmd.args.push("-m64".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if !nvcc && self.pic.unwrap_or(!target.contains("i686") && !target.contains("windows-gnu")) {
|
|
||||||
cmd.args.push("-fPIC".into());
|
|
||||||
} else if nvcc && self.pic.unwrap_or(false) {
|
|
||||||
cmd.args.push("-Xcompiler".into());
|
|
||||||
cmd.args.push("\'-fPIC\'".into());
|
|
||||||
}
|
|
||||||
if target.contains("musl") {
|
|
||||||
cmd.args.push("-static".into());
|
|
||||||
}
|
|
||||||
|
|
||||||
if target.starts_with("armv7-unknown-linux-") {
|
|
||||||
cmd.args.push("-march=armv7-a".into());
|
|
||||||
}
|
|
||||||
if target.starts_with("arm-unknown-linux-") {
|
|
||||||
cmd.args.push("-march=armv6".into());
|
|
||||||
cmd.args.push("-marm".into());
|
|
||||||
}
|
|
||||||
if target.starts_with("i586-unknown-linux-") {
|
|
||||||
cmd.args.push("-march=pentium".into());
|
|
||||||
}
|
|
||||||
if target.starts_with("i686-unknown-linux-") {
|
|
||||||
cmd.args.push("-march=i686".into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.cpp && !msvc {
|
|
||||||
if let Some(ref stdlib) = self.cpp_set_stdlib {
|
|
||||||
cmd.args.push(format!("-stdlib=lib{}", stdlib).into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for directory in self.include_directories.iter() {
|
|
||||||
cmd.args.push(if msvc {"/I"} else {"-I"}.into());
|
|
||||||
cmd.args.push(directory.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
for flag in self.flags.iter() {
|
|
||||||
cmd.args.push(flag.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
for &(ref key, ref value) in self.definitions.iter() {
|
|
||||||
let lead = if msvc {"/"} else {"-"};
|
|
||||||
if let &Some(ref value) = value {
|
|
||||||
cmd.args.push(format!("{}D{}={}", lead, key, value).into());
|
|
||||||
} else {
|
|
||||||
cmd.args.push(format!("{}D{}", lead, key).into());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
fn msvc_macro_assembler(&self) -> (Command, String) {
|
|
||||||
let target = self.get_target();
|
|
||||||
let tool = if target.contains("x86_64") {"ml64.exe"} else {"ml.exe"};
|
|
||||||
let mut cmd = windows_registry::find(&target, tool).unwrap_or_else(|| {
|
|
||||||
self.cmd(tool)
|
|
||||||
});
|
|
||||||
for directory in self.include_directories.iter() {
|
|
||||||
cmd.arg("/I").arg(directory);
|
|
||||||
}
|
|
||||||
for &(ref key, ref value) in self.definitions.iter() {
|
|
||||||
if let &Some(ref value) = value {
|
|
||||||
cmd.arg(&format!("/D{}={}", key, value));
|
|
||||||
} else {
|
|
||||||
cmd.arg(&format!("/D{}", key));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if target.contains("i686") || target.contains("i586") {
|
|
||||||
cmd.arg("/safeseh");
|
|
||||||
}
|
|
||||||
for flag in self.flags.iter() {
|
|
||||||
cmd.arg(flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
(cmd, tool.to_string())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assemble(&self, lib_name: &str, dst: &Path, objects: &[PathBuf]) {
|
|
||||||
// Delete the destination if it exists as the `ar` tool at least on Unix
|
|
||||||
// appends to it, which we don't want.
|
|
||||||
let _ = fs::remove_file(&dst);
|
|
||||||
|
|
||||||
let target = self.get_target();
|
|
||||||
if target.contains("msvc") {
|
|
||||||
let mut cmd = match self.archiver {
|
|
||||||
Some(ref s) => self.cmd(s),
|
|
||||||
None => windows_registry::find(&target, "lib.exe")
|
|
||||||
.unwrap_or(self.cmd("lib.exe")),
|
|
||||||
};
|
|
||||||
let mut out = OsString::from("/OUT:");
|
|
||||||
out.push(dst);
|
|
||||||
run(cmd.arg(out).arg("/nologo")
|
|
||||||
.args(objects)
|
|
||||||
.args(&self.objects), "lib.exe");
|
|
||||||
|
|
||||||
// The Rust compiler will look for libfoo.a and foo.lib, but the
|
|
||||||
// MSVC linker will also be passed foo.lib, so be sure that both
|
|
||||||
// exist for now.
|
|
||||||
let lib_dst = dst.with_file_name(format!("{}.lib", lib_name));
|
|
||||||
let _ = fs::remove_file(&lib_dst);
|
|
||||||
fs::hard_link(&dst, &lib_dst).or_else(|_| {
|
|
||||||
//if hard-link fails, just copy (ignoring the number of bytes written)
|
|
||||||
fs::copy(&dst, &lib_dst).map(|_| ())
|
|
||||||
}).ok().expect("Copying from {:?} to {:?} failed.");;
|
|
||||||
} else {
|
|
||||||
let ar = self.get_ar();
|
|
||||||
let cmd = ar.file_name().unwrap().to_string_lossy();
|
|
||||||
run(self.cmd(&ar).arg("crus")
|
|
||||||
.arg(dst)
|
|
||||||
.args(objects)
|
|
||||||
.args(&self.objects), &cmd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ios_flags(&self, cmd: &mut Tool) {
|
|
||||||
enum ArchSpec {
|
|
||||||
Device(&'static str),
|
|
||||||
Simulator(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
let target = self.get_target();
|
|
||||||
let arch = target.split('-').nth(0).unwrap();
|
|
||||||
let arch = match arch {
|
|
||||||
"arm" | "armv7" | "thumbv7" => ArchSpec::Device("armv7"),
|
|
||||||
"armv7s" | "thumbv7s" => ArchSpec::Device("armv7s"),
|
|
||||||
"arm64" | "aarch64" => ArchSpec::Device("arm64"),
|
|
||||||
"i386" | "i686" => ArchSpec::Simulator("-m32"),
|
|
||||||
"x86_64" => ArchSpec::Simulator("-m64"),
|
|
||||||
_ => fail("Unknown arch for iOS target")
|
|
||||||
};
|
|
||||||
|
|
||||||
let sdk = match arch {
|
|
||||||
ArchSpec::Device(arch) => {
|
|
||||||
cmd.args.push("-arch".into());
|
|
||||||
cmd.args.push(arch.into());
|
|
||||||
cmd.args.push("-miphoneos-version-min=7.0".into());
|
|
||||||
"iphoneos"
|
|
||||||
},
|
|
||||||
ArchSpec::Simulator(arch) => {
|
|
||||||
cmd.args.push(arch.into());
|
|
||||||
cmd.args.push("-mios-simulator-version-min=7.0".into());
|
|
||||||
"iphonesimulator"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
self.print(&format!("Detecting iOS SDK path for {}", sdk));
|
|
||||||
let sdk_path = self.cmd("xcrun")
|
|
||||||
.arg("--show-sdk-path")
|
|
||||||
.arg("--sdk")
|
|
||||||
.arg(sdk)
|
|
||||||
.stderr(Stdio::inherit())
|
|
||||||
.output()
|
|
||||||
.unwrap()
|
|
||||||
.stdout;
|
|
||||||
|
|
||||||
let sdk_path = String::from_utf8(sdk_path).unwrap();
|
|
||||||
|
|
||||||
cmd.args.push("-isysroot".into());
|
|
||||||
cmd.args.push(sdk_path.trim().into());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cmd<P: AsRef<OsStr>>(&self, prog: P) -> Command {
|
|
||||||
let mut cmd = Command::new(prog);
|
|
||||||
for &(ref a, ref b) in self.env.iter() {
|
|
||||||
cmd.env(a, b);
|
|
||||||
}
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_base_compiler(&self) -> Tool {
|
|
||||||
if let Some(ref c) = self.compiler {
|
|
||||||
return Tool::new(c.clone())
|
|
||||||
}
|
|
||||||
let host = self.get_host();
|
|
||||||
let target = self.get_target();
|
|
||||||
let (env, msvc, gnu, default) = if self.cpp {
|
|
||||||
("CXX", "cl.exe", "g++", "c++")
|
|
||||||
} else {
|
|
||||||
("CC", "cl.exe", "gcc", "cc")
|
|
||||||
};
|
|
||||||
self.env_tool(env).map(|(tool, args)| {
|
|
||||||
let mut t = Tool::new(PathBuf::from(tool));
|
|
||||||
for arg in args {
|
|
||||||
t.args.push(arg.into());
|
|
||||||
}
|
|
||||||
return t
|
|
||||||
}).or_else(|| {
|
|
||||||
windows_registry::find_tool(&target, "cl.exe")
|
|
||||||
}).unwrap_or_else(|| {
|
|
||||||
let compiler = if host.contains("windows") &&
|
|
||||||
target.contains("windows") {
|
|
||||||
if target.contains("msvc") {
|
|
||||||
msvc.to_string()
|
|
||||||
} else {
|
|
||||||
format!("{}.exe", gnu)
|
|
||||||
}
|
|
||||||
} else if target.contains("android") {
|
|
||||||
format!("{}-{}", target, gnu)
|
|
||||||
} else if self.get_host() != target {
|
|
||||||
let prefix = match &target[..] {
|
|
||||||
"aarch64-unknown-linux-gnu" => Some("aarch64-linux-gnu"),
|
|
||||||
"arm-unknown-linux-gnueabi" => Some("arm-linux-gnueabi"),
|
|
||||||
"arm-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
|
|
||||||
"armv7-unknown-linux-gnueabihf" => Some("arm-linux-gnueabihf"),
|
|
||||||
"arm-unknown-linux-musleabi" => Some("arm-linux-musleabi"),
|
|
||||||
"arm-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
|
|
||||||
"armv7-unknown-linux-musleabihf" => Some("arm-linux-musleabihf"),
|
|
||||||
"powerpc-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
|
|
||||||
"powerpc64-unknown-linux-gnu" => Some("powerpc-linux-gnu"),
|
|
||||||
"powerpc64le-unknown-linux-gnu" => Some("powerpc64le-linux-gnu"),
|
|
||||||
"mips-unknown-linux-gnu" => Some("mips-linux-gnu"),
|
|
||||||
"mipsel-unknown-linux-gnu" => Some("mipsel-linux-gnu"),
|
|
||||||
"i686-pc-windows-gnu" => Some("i686-w64-mingw32"),
|
|
||||||
"x86_64-pc-windows-gnu" => Some("x86_64-w64-mingw32"),
|
|
||||||
"x86_64-unknown-linux-musl" => Some("musl"),
|
|
||||||
"x86_64-rumprun-netbsd" => Some("x86_64-rumprun-netbsd"),
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
match prefix {
|
|
||||||
Some(prefix) => format!("{}-{}", prefix, gnu),
|
|
||||||
None => default.to_string(),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
default.to_string()
|
|
||||||
};
|
|
||||||
Tool::new(PathBuf::from(compiler))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_var(&self, var_base: &str) -> Result<String, String> {
|
|
||||||
let target = self.get_target();
|
|
||||||
let host = self.get_host();
|
|
||||||
let kind = if host == target {"HOST"} else {"TARGET"};
|
|
||||||
let target_u = target.replace("-", "_");
|
|
||||||
let res = self.getenv(&format!("{}_{}", var_base, target))
|
|
||||||
.or_else(|| self.getenv(&format!("{}_{}", var_base, target_u)))
|
|
||||||
.or_else(|| self.getenv(&format!("{}_{}", kind, var_base)))
|
|
||||||
.or_else(|| self.getenv(var_base));
|
|
||||||
|
|
||||||
match res {
|
|
||||||
Some(res) => Ok(res),
|
|
||||||
None => Err("could not get environment variable".to_string()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn envflags(&self, name: &str) -> Vec<String> {
|
|
||||||
self.get_var(name).unwrap_or(String::new())
|
|
||||||
.split(|c: char| c.is_whitespace()).filter(|s| !s.is_empty())
|
|
||||||
.map(|s| s.to_string())
|
|
||||||
.collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn env_tool(&self, name: &str) -> Option<(String, Vec<String>)> {
|
|
||||||
self.get_var(name).ok().map(|tool| {
|
|
||||||
let whitelist = ["ccache", "distcc"];
|
|
||||||
for t in whitelist.iter() {
|
|
||||||
if tool.starts_with(t) && tool[t.len()..].starts_with(" ") {
|
|
||||||
return (t.to_string(),
|
|
||||||
vec![tool[t.len()..].trim_left().to_string()])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(tool, Vec::new())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the default C++ standard library for the current target: `libc++`
|
|
||||||
/// for OS X and `libstdc++` for anything else.
|
|
||||||
fn get_cpp_link_stdlib(&self) -> Option<String> {
|
|
||||||
self.cpp_link_stdlib.clone().unwrap_or_else(|| {
|
|
||||||
let target = self.get_target();
|
|
||||||
if target.contains("msvc") {
|
|
||||||
None
|
|
||||||
} else if target.contains("darwin") {
|
|
||||||
Some("c++".to_string())
|
|
||||||
} else {
|
|
||||||
Some("stdc++".to_string())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_ar(&self) -> PathBuf {
|
|
||||||
self.archiver.clone().or_else(|| {
|
|
||||||
self.get_var("AR").map(PathBuf::from).ok()
|
|
||||||
}).unwrap_or_else(|| {
|
|
||||||
if self.get_target().contains("android") {
|
|
||||||
PathBuf::from(format!("{}-ar", self.get_target()))
|
|
||||||
} else {
|
|
||||||
PathBuf::from("ar")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_target(&self) -> String {
|
|
||||||
self.target.clone().unwrap_or_else(|| self.getenv_unwrap("TARGET"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_host(&self) -> String {
|
|
||||||
self.host.clone().unwrap_or_else(|| self.getenv_unwrap("HOST"))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_opt_level(&self) -> u32 {
|
|
||||||
self.opt_level.unwrap_or_else(|| {
|
|
||||||
self.getenv_unwrap("OPT_LEVEL").parse().unwrap()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_debug(&self) -> bool {
|
|
||||||
self.debug.unwrap_or_else(|| self.getenv_unwrap("PROFILE") == "debug")
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_out_dir(&self) -> PathBuf {
|
|
||||||
self.out_dir.clone().unwrap_or_else(|| {
|
|
||||||
env::var_os("OUT_DIR").map(PathBuf::from).unwrap()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getenv(&self, v: &str) -> Option<String> {
|
|
||||||
let r = env::var(v).ok();
|
|
||||||
self.print(&format!("{} = {:?}", v, r));
|
|
||||||
r
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getenv_unwrap(&self, v: &str) -> String {
|
|
||||||
match self.getenv(v) {
|
|
||||||
Some(s) => s,
|
|
||||||
None => fail(&format!("environment variable `{}` not defined", v)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn print(&self, s: &str) {
|
|
||||||
if self.cargo_metadata {
|
|
||||||
println!("{}", s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Tool {
|
|
||||||
fn new(path: PathBuf) -> Tool {
|
|
||||||
Tool {
|
|
||||||
path: path,
|
|
||||||
args: Vec::new(),
|
|
||||||
env: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Converts this compiler into a `Command` that's ready to be run.
|
|
||||||
///
|
|
||||||
/// This is useful for when the compiler needs to be executed and the
|
|
||||||
/// command returned will already have the initial arguments and environment
|
|
||||||
/// variables configured.
|
|
||||||
pub fn to_command(&self) -> Command {
|
|
||||||
let mut cmd = Command::new(&self.path);
|
|
||||||
cmd.args(&self.args);
|
|
||||||
for &(ref k, ref v) in self.env.iter() {
|
|
||||||
cmd.env(k, v);
|
|
||||||
}
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the path for this compiler.
|
|
||||||
///
|
|
||||||
/// Note that this may not be a path to a file on the filesystem, e.g. "cc",
|
|
||||||
/// but rather something which will be resolved when a process is spawned.
|
|
||||||
pub fn path(&self) -> &Path {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the default set of arguments to the compiler needed to produce
|
|
||||||
/// executables for the target this compiler generates.
|
|
||||||
pub fn args(&self) -> &[OsString] {
|
|
||||||
&self.args
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the set of environment variables needed for this compiler to
|
|
||||||
/// operate.
|
|
||||||
///
|
|
||||||
/// This is typically only used for MSVC compilers currently.
|
|
||||||
pub fn env(&self) -> &[(OsString, OsString)] {
|
|
||||||
&self.env
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn run(cmd: &mut Command, program: &str) {
|
|
||||||
println!("running: {:?}", cmd);
|
|
||||||
// Capture the standard error coming from these programs, and write it out
|
|
||||||
// with cargo:warning= prefixes. Note that this is a bit wonky to avoid
|
|
||||||
// requiring the output to be UTF-8, we instead just ship bytes from one
|
|
||||||
// location to another.
|
|
||||||
let spawn_result = match cmd.stderr(Stdio::piped()).spawn() {
|
|
||||||
Ok(mut child) => {
|
|
||||||
let stderr = BufReader::new(child.stderr.take().unwrap());
|
|
||||||
for line in stderr.split(b'\n').filter_map(|l| l.ok()) {
|
|
||||||
print!("cargo:warning=");
|
|
||||||
std::io::stdout().write_all(&line).unwrap();
|
|
||||||
println!("");
|
|
||||||
}
|
|
||||||
child.wait()
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
};
|
|
||||||
let status = match spawn_result {
|
|
||||||
Ok(status) => status,
|
|
||||||
Err(ref e) if e.kind() == io::ErrorKind::NotFound => {
|
|
||||||
let extra = if cfg!(windows) {
|
|
||||||
" (see https://github.com/alexcrichton/gcc-rs#compile-time-requirements \
|
|
||||||
for help)"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
fail(&format!("failed to execute command: {}\nIs `{}` \
|
|
||||||
not installed?{}", e, program, extra));
|
|
||||||
}
|
|
||||||
Err(e) => fail(&format!("failed to execute command: {}", e)),
|
|
||||||
};
|
|
||||||
println!("{:?}", status);
|
|
||||||
if !status.success() {
|
|
||||||
fail(&format!("command did not execute successfully, got: {}", status));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fail(s: &str) -> ! {
|
|
||||||
println!("\n\n{}\n\n", s);
|
|
||||||
panic!()
|
|
||||||
}
|
|
||||||
169
third_party/rust/gcc/src/registry.rs
vendored
169
third_party/rust/gcc/src/registry.rs
vendored
|
|
@ -1,169 +0,0 @@
|
||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
use std::ffi::{OsString, OsStr};
|
|
||||||
use std::io;
|
|
||||||
use std::ops::RangeFrom;
|
|
||||||
use std::os::raw;
|
|
||||||
use std::os::windows::prelude::*;
|
|
||||||
|
|
||||||
pub struct RegistryKey(Repr);
|
|
||||||
|
|
||||||
type HKEY = *mut u8;
|
|
||||||
type DWORD = u32;
|
|
||||||
type LPDWORD = *mut DWORD;
|
|
||||||
type LPCWSTR = *const u16;
|
|
||||||
type LPWSTR = *mut u16;
|
|
||||||
type LONG = raw::c_long;
|
|
||||||
type PHKEY = *mut HKEY;
|
|
||||||
type PFILETIME = *mut u8;
|
|
||||||
type LPBYTE = *mut u8;
|
|
||||||
type REGSAM = u32;
|
|
||||||
|
|
||||||
const ERROR_SUCCESS: DWORD = 0;
|
|
||||||
const ERROR_NO_MORE_ITEMS: DWORD = 259;
|
|
||||||
const HKEY_LOCAL_MACHINE: HKEY = 0x80000002 as HKEY;
|
|
||||||
const REG_SZ: DWORD = 1;
|
|
||||||
const KEY_READ: DWORD = 0x20019;
|
|
||||||
const KEY_WOW64_32KEY: DWORD = 0x200;
|
|
||||||
|
|
||||||
#[link(name = "advapi32")]
|
|
||||||
extern "system" {
|
|
||||||
fn RegOpenKeyExW(key: HKEY,
|
|
||||||
lpSubKey: LPCWSTR,
|
|
||||||
ulOptions: DWORD,
|
|
||||||
samDesired: REGSAM,
|
|
||||||
phkResult: PHKEY) -> LONG;
|
|
||||||
fn RegEnumKeyExW(key: HKEY,
|
|
||||||
dwIndex: DWORD,
|
|
||||||
lpName: LPWSTR,
|
|
||||||
lpcName: LPDWORD,
|
|
||||||
lpReserved: LPDWORD,
|
|
||||||
lpClass: LPWSTR,
|
|
||||||
lpcClass: LPDWORD,
|
|
||||||
lpftLastWriteTime: PFILETIME) -> LONG;
|
|
||||||
fn RegQueryValueExW(hKey: HKEY,
|
|
||||||
lpValueName: LPCWSTR,
|
|
||||||
lpReserved: LPDWORD,
|
|
||||||
lpType: LPDWORD,
|
|
||||||
lpData: LPBYTE,
|
|
||||||
lpcbData: LPDWORD) -> LONG;
|
|
||||||
fn RegCloseKey(hKey: HKEY) -> LONG;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct OwnedKey(HKEY);
|
|
||||||
|
|
||||||
enum Repr {
|
|
||||||
Const(HKEY),
|
|
||||||
Owned(OwnedKey),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Iter<'a> {
|
|
||||||
idx: RangeFrom<DWORD>,
|
|
||||||
key: &'a RegistryKey,
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe impl Sync for Repr {}
|
|
||||||
unsafe impl Send for Repr {}
|
|
||||||
|
|
||||||
pub static LOCAL_MACHINE: RegistryKey =
|
|
||||||
RegistryKey(Repr::Const(HKEY_LOCAL_MACHINE));
|
|
||||||
|
|
||||||
impl RegistryKey {
|
|
||||||
fn raw(&self) -> HKEY {
|
|
||||||
match self.0 {
|
|
||||||
Repr::Const(val) => val,
|
|
||||||
Repr::Owned(ref val) => val.0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn open(&self, key: &OsStr) -> io::Result<RegistryKey> {
|
|
||||||
let key = key.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
|
||||||
let mut ret = 0 as *mut _;
|
|
||||||
let err = unsafe {
|
|
||||||
RegOpenKeyExW(self.raw(), key.as_ptr(), 0,
|
|
||||||
KEY_READ | KEY_WOW64_32KEY, &mut ret)
|
|
||||||
};
|
|
||||||
if err == ERROR_SUCCESS as LONG {
|
|
||||||
Ok(RegistryKey(Repr::Owned(OwnedKey(ret))))
|
|
||||||
} else {
|
|
||||||
Err(io::Error::from_raw_os_error(err as i32))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn iter(&self) -> Iter {
|
|
||||||
Iter { idx: 0.., key: self }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn query_str(&self, name: &str) -> io::Result<OsString> {
|
|
||||||
let name: &OsStr = name.as_ref();
|
|
||||||
let name = name.encode_wide().chain(Some(0)).collect::<Vec<_>>();
|
|
||||||
let mut len = 0;
|
|
||||||
let mut kind = 0;
|
|
||||||
unsafe {
|
|
||||||
let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _,
|
|
||||||
&mut kind, 0 as *mut _, &mut len);
|
|
||||||
if err != ERROR_SUCCESS as LONG {
|
|
||||||
return Err(io::Error::from_raw_os_error(err as i32))
|
|
||||||
}
|
|
||||||
if kind != REG_SZ {
|
|
||||||
return Err(io::Error::new(io::ErrorKind::Other,
|
|
||||||
"registry key wasn't a string"))
|
|
||||||
}
|
|
||||||
|
|
||||||
// The length here is the length in bytes, but we're using wide
|
|
||||||
// characters so we need to be sure to halve it for the capacity
|
|
||||||
// passed in.
|
|
||||||
let mut v = Vec::with_capacity(len as usize / 2);
|
|
||||||
let err = RegQueryValueExW(self.raw(), name.as_ptr(), 0 as *mut _,
|
|
||||||
0 as *mut _, v.as_mut_ptr() as *mut _,
|
|
||||||
&mut len);
|
|
||||||
if err != ERROR_SUCCESS as LONG {
|
|
||||||
return Err(io::Error::from_raw_os_error(err as i32))
|
|
||||||
}
|
|
||||||
v.set_len(len as usize / 2);
|
|
||||||
|
|
||||||
// Some registry keys may have a terminating nul character, but
|
|
||||||
// we're not interested in that, so chop it off if it's there.
|
|
||||||
if v[v.len() - 1] == 0 {
|
|
||||||
v.pop();
|
|
||||||
}
|
|
||||||
Ok(OsString::from_wide(&v))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for OwnedKey {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { RegCloseKey(self.0); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> Iterator for Iter<'a> {
|
|
||||||
type Item = io::Result<OsString>;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<io::Result<OsString>> {
|
|
||||||
self.idx.next().and_then(|i| unsafe {
|
|
||||||
let mut v = Vec::with_capacity(256);
|
|
||||||
let mut len = v.capacity() as DWORD;
|
|
||||||
let ret = RegEnumKeyExW(self.key.raw(), i, v.as_mut_ptr(), &mut len,
|
|
||||||
0 as *mut _, 0 as *mut _, 0 as *mut _,
|
|
||||||
0 as *mut _);
|
|
||||||
if ret == ERROR_NO_MORE_ITEMS as LONG {
|
|
||||||
None
|
|
||||||
} else if ret != ERROR_SUCCESS as LONG {
|
|
||||||
Some(Err(io::Error::from_raw_os_error(ret as i32)))
|
|
||||||
} else {
|
|
||||||
v.set_len(len as usize);
|
|
||||||
Some(Ok(OsString::from_wide(&v)))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
423
third_party/rust/gcc/src/windows_registry.rs
vendored
423
third_party/rust/gcc/src/windows_registry.rs
vendored
|
|
@ -1,423 +0,0 @@
|
||||||
// Copyright 2015 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.
|
|
||||||
|
|
||||||
//! A helper module to probe the Windows Registry when looking for
|
|
||||||
//! windows-specific tools.
|
|
||||||
|
|
||||||
use std::process::Command;
|
|
||||||
|
|
||||||
use Tool;
|
|
||||||
|
|
||||||
macro_rules! otry {
|
|
||||||
($expr:expr) => (match $expr {
|
|
||||||
Some(val) => val,
|
|
||||||
None => return None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attempts to find a tool within an MSVC installation using the Windows
|
|
||||||
/// registry as a point to search from.
|
|
||||||
///
|
|
||||||
/// The `target` argument is the target that the tool should work for (e.g.
|
|
||||||
/// compile or link for) and the `tool` argument is the tool to find (e.g.
|
|
||||||
/// `cl.exe` or `link.exe`).
|
|
||||||
///
|
|
||||||
/// This function will return `None` if the tool could not be found, or it will
|
|
||||||
/// return `Some(cmd)` which represents a command that's ready to execute the
|
|
||||||
/// tool with the appropriate environment variables set.
|
|
||||||
///
|
|
||||||
/// Note that this function always returns `None` for non-MSVC targets.
|
|
||||||
pub fn find(target: &str, tool: &str) -> Option<Command> {
|
|
||||||
find_tool(target, tool).map(|c| c.to_command())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similar to the `find` function above, this function will attempt the same
|
|
||||||
/// operation (finding a MSVC tool in a local install) but instead returns a
|
|
||||||
/// `Tool` which may be introspected.
|
|
||||||
#[cfg(not(windows))]
|
|
||||||
pub fn find_tool(_target: &str, _tool: &str) -> Option<Tool> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Documented above.
|
|
||||||
#[cfg(windows)]
|
|
||||||
pub fn find_tool(target: &str, tool: &str) -> Option<Tool> {
|
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsString;
|
|
||||||
use std::mem;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use registry::{RegistryKey, LOCAL_MACHINE};
|
|
||||||
|
|
||||||
struct MsvcTool {
|
|
||||||
tool: PathBuf,
|
|
||||||
libs: Vec<PathBuf>,
|
|
||||||
path: Vec<PathBuf>,
|
|
||||||
include: Vec<PathBuf>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MsvcTool {
|
|
||||||
fn new(tool: PathBuf) -> MsvcTool {
|
|
||||||
MsvcTool {
|
|
||||||
tool: tool,
|
|
||||||
libs: Vec::new(),
|
|
||||||
path: Vec::new(),
|
|
||||||
include: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn into_tool(self) -> Tool {
|
|
||||||
let MsvcTool { tool, libs, path, include } = self;
|
|
||||||
let mut tool = Tool::new(tool.into());
|
|
||||||
add_env(&mut tool, "LIB", libs);
|
|
||||||
add_env(&mut tool, "PATH", path);
|
|
||||||
add_env(&mut tool, "INCLUDE", include);
|
|
||||||
return tool
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This logic is all tailored for MSVC, if we're not that then bail out
|
|
||||||
// early.
|
|
||||||
if !target.contains("msvc") {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
|
|
||||||
// Looks like msbuild isn't located in the same location as other tools like
|
|
||||||
// cl.exe and lib.exe. To handle this we probe for it manually with
|
|
||||||
// dedicated registry keys.
|
|
||||||
if tool.contains("msbuild") {
|
|
||||||
return find_msbuild(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// If VCINSTALLDIR is set, then someone's probably already run vcvars and we
|
|
||||||
// should just find whatever that indicates.
|
|
||||||
if env::var_os("VCINSTALLDIR").is_some() {
|
|
||||||
return env::var_os("PATH").and_then(|path| {
|
|
||||||
env::split_paths(&path).map(|p| p.join(tool)).find(|p| p.exists())
|
|
||||||
}).map(|path| {
|
|
||||||
Tool::new(path.into())
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ok, if we're here, now comes the fun part of the probing. Default shells
|
|
||||||
// or shells like MSYS aren't really configured to execute `cl.exe` and the
|
|
||||||
// various compiler tools shipped as part of Visual Studio. Here we try to
|
|
||||||
// first find the relevant tool, then we also have to be sure to fill in
|
|
||||||
// environment variables like `LIB`, `INCLUDE`, and `PATH` to ensure that
|
|
||||||
// the tool is actually usable.
|
|
||||||
|
|
||||||
return find_msvc_latest(tool, target, "15.0").or_else(|| {
|
|
||||||
find_msvc_latest(tool, target, "14.0")
|
|
||||||
}).or_else(|| {
|
|
||||||
find_msvc_12(tool, target)
|
|
||||||
}).or_else(|| {
|
|
||||||
find_msvc_11(tool, target)
|
|
||||||
});
|
|
||||||
|
|
||||||
// For MSVC 14 or newer we need to find the Universal CRT as well as either
|
|
||||||
// the Windows 10 SDK or Windows 8.1 SDK.
|
|
||||||
fn find_msvc_latest(tool: &str, target: &str, ver: &str) -> Option<Tool> {
|
|
||||||
let vcdir = otry!(get_vc_dir(ver));
|
|
||||||
let mut tool = otry!(get_tool(tool, &vcdir, target));
|
|
||||||
let sub = otry!(lib_subdir(target));
|
|
||||||
let (ucrt, ucrt_version) = otry!(get_ucrt_dir());
|
|
||||||
|
|
||||||
let ucrt_include = ucrt.join("include").join(&ucrt_version);
|
|
||||||
tool.include.push(ucrt_include.join("ucrt"));
|
|
||||||
|
|
||||||
let ucrt_lib = ucrt.join("lib").join(&ucrt_version);
|
|
||||||
tool.libs.push(ucrt_lib.join("ucrt").join(sub));
|
|
||||||
|
|
||||||
if let Some((sdk, version)) = get_sdk10_dir() {
|
|
||||||
tool.path.push(sdk.join("bin").join(sub));
|
|
||||||
let sdk_lib = sdk.join("lib").join(&version);
|
|
||||||
tool.libs.push(sdk_lib.join("um").join(sub));
|
|
||||||
let sdk_include = sdk.join("include").join(&version);
|
|
||||||
tool.include.push(sdk_include.join("um"));
|
|
||||||
tool.include.push(sdk_include.join("winrt"));
|
|
||||||
tool.include.push(sdk_include.join("shared"));
|
|
||||||
} else if let Some(sdk) = get_sdk81_dir() {
|
|
||||||
tool.path.push(sdk.join("bin").join(sub));
|
|
||||||
let sdk_lib = sdk.join("lib").join("winv6.3");
|
|
||||||
tool.libs.push(sdk_lib.join("um").join(sub));
|
|
||||||
let sdk_include = sdk.join("include");
|
|
||||||
tool.include.push(sdk_include.join("um"));
|
|
||||||
tool.include.push(sdk_include.join("winrt"));
|
|
||||||
tool.include.push(sdk_include.join("shared"));
|
|
||||||
} else {
|
|
||||||
return None
|
|
||||||
}
|
|
||||||
Some(tool.into_tool())
|
|
||||||
}
|
|
||||||
|
|
||||||
// For MSVC 12 we need to find the Windows 8.1 SDK.
|
|
||||||
fn find_msvc_12(tool: &str, target: &str) -> Option<Tool> {
|
|
||||||
let vcdir = otry!(get_vc_dir("12.0"));
|
|
||||||
let mut tool = otry!(get_tool(tool, &vcdir, target));
|
|
||||||
let sub = otry!(lib_subdir(target));
|
|
||||||
let sdk81 = otry!(get_sdk81_dir());
|
|
||||||
tool.path.push(sdk81.join("bin").join(sub));
|
|
||||||
let sdk_lib = sdk81.join("lib").join("winv6.3");
|
|
||||||
tool.libs.push(sdk_lib.join("um").join(sub));
|
|
||||||
let sdk_include = sdk81.join("include");
|
|
||||||
tool.include.push(sdk_include.join("shared"));
|
|
||||||
tool.include.push(sdk_include.join("um"));
|
|
||||||
tool.include.push(sdk_include.join("winrt"));
|
|
||||||
Some(tool.into_tool())
|
|
||||||
}
|
|
||||||
|
|
||||||
// For MSVC 11 we need to find the Windows 8 SDK.
|
|
||||||
fn find_msvc_11(tool: &str, target: &str) -> Option<Tool> {
|
|
||||||
let vcdir = otry!(get_vc_dir("11.0"));
|
|
||||||
let mut tool = otry!(get_tool(tool, &vcdir, target));
|
|
||||||
let sub = otry!(lib_subdir(target));
|
|
||||||
let sdk8 = otry!(get_sdk8_dir());
|
|
||||||
tool.path.push(sdk8.join("bin").join(sub));
|
|
||||||
let sdk_lib = sdk8.join("lib").join("win8");
|
|
||||||
tool.libs.push(sdk_lib.join("um").join(sub));
|
|
||||||
let sdk_include = sdk8.join("include");
|
|
||||||
tool.include.push(sdk_include.join("shared"));
|
|
||||||
tool.include.push(sdk_include.join("um"));
|
|
||||||
tool.include.push(sdk_include.join("winrt"));
|
|
||||||
Some(tool.into_tool())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn add_env(tool: &mut Tool, env: &str, paths: Vec<PathBuf>) {
|
|
||||||
let prev = env::var_os(env).unwrap_or(OsString::new());
|
|
||||||
let prev = env::split_paths(&prev);
|
|
||||||
let new = paths.into_iter().chain(prev);
|
|
||||||
tool.env.push((env.to_string().into(), env::join_paths(new).unwrap()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a possible MSVC installation directory, we look for the linker and
|
|
||||||
// then add the MSVC library path.
|
|
||||||
fn get_tool(tool: &str, path: &Path, target: &str) -> Option<MsvcTool> {
|
|
||||||
bin_subdir(target).into_iter().map(|(sub, host)| {
|
|
||||||
(path.join("bin").join(sub).join(tool),
|
|
||||||
path.join("bin").join(host))
|
|
||||||
}).filter(|&(ref path, _)| {
|
|
||||||
path.is_file()
|
|
||||||
}).map(|(path, host)| {
|
|
||||||
let mut tool = MsvcTool::new(path);
|
|
||||||
tool.path.push(host);
|
|
||||||
tool
|
|
||||||
}).filter_map(|mut tool| {
|
|
||||||
let sub = otry!(vc_lib_subdir(target));
|
|
||||||
tool.libs.push(path.join("lib").join(sub));
|
|
||||||
tool.include.push(path.join("include"));
|
|
||||||
Some(tool)
|
|
||||||
}).next()
|
|
||||||
}
|
|
||||||
|
|
||||||
// To find MSVC we look in a specific registry key for the version we are
|
|
||||||
// trying to find.
|
|
||||||
fn get_vc_dir(ver: &str) -> Option<PathBuf> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\VisualStudio\SxS\VC7";
|
|
||||||
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
|
|
||||||
let path = otry!(key.query_str(ver).ok());
|
|
||||||
Some(path.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
// To find the Universal CRT we look in a specific registry key for where
|
|
||||||
// all the Universal CRTs are located and then sort them asciibetically to
|
|
||||||
// find the newest version. While this sort of sorting isn't ideal, it is
|
|
||||||
// what vcvars does so that's good enough for us.
|
|
||||||
//
|
|
||||||
// Returns a pair of (root, version) for the ucrt dir if found
|
|
||||||
fn get_ucrt_dir() -> Option<(PathBuf, String)> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\Windows Kits\Installed Roots";
|
|
||||||
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
|
|
||||||
let root = otry!(key.query_str("KitsRoot10").ok());
|
|
||||||
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
|
|
||||||
let max_libdir = otry!(readdir.filter_map(|dir| {
|
|
||||||
dir.ok()
|
|
||||||
}).map(|dir| {
|
|
||||||
dir.path()
|
|
||||||
}).filter(|dir| {
|
|
||||||
dir.components().last().and_then(|c| {
|
|
||||||
c.as_os_str().to_str()
|
|
||||||
}).map(|c| {
|
|
||||||
c.starts_with("10.") && dir.join("ucrt").is_dir()
|
|
||||||
}).unwrap_or(false)
|
|
||||||
}).max());
|
|
||||||
let version = max_libdir.components().last().unwrap();
|
|
||||||
let version = version.as_os_str().to_str().unwrap().to_string();
|
|
||||||
Some((root.into(), version))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Vcvars finds the correct version of the Windows 10 SDK by looking
|
|
||||||
// for the include `um\Windows.h` because sometimes a given version will
|
|
||||||
// only have UCRT bits without the rest of the SDK. Since we only care about
|
|
||||||
// libraries and not includes, we instead look for `um\x64\kernel32.lib`.
|
|
||||||
// Since the 32-bit and 64-bit libraries are always installed together we
|
|
||||||
// only need to bother checking x64, making this code a tiny bit simpler.
|
|
||||||
// Like we do for the Universal CRT, we sort the possibilities
|
|
||||||
// asciibetically to find the newest one as that is what vcvars does.
|
|
||||||
fn get_sdk10_dir() -> Option<(PathBuf, String)> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v10.0";
|
|
||||||
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
|
|
||||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
|
||||||
let readdir = otry!(Path::new(&root).join("lib").read_dir().ok());
|
|
||||||
let mut dirs = readdir.filter_map(|dir| dir.ok())
|
|
||||||
.map(|dir| dir.path())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
dirs.sort();
|
|
||||||
let dir = otry!(dirs.into_iter().rev().filter(|dir| {
|
|
||||||
dir.join("um").join("x64").join("kernel32.lib").is_file()
|
|
||||||
}).next());
|
|
||||||
let version = dir.components().last().unwrap();
|
|
||||||
let version = version.as_os_str().to_str().unwrap().to_string();
|
|
||||||
Some((root.into(), version))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interestingly there are several subdirectories, `win7` `win8` and
|
|
||||||
// `winv6.3`. Vcvars seems to only care about `winv6.3` though, so the same
|
|
||||||
// applies to us. Note that if we were targetting kernel mode drivers
|
|
||||||
// instead of user mode applications, we would care.
|
|
||||||
fn get_sdk81_dir() -> Option<PathBuf> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.1";
|
|
||||||
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
|
|
||||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
|
||||||
Some(root.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_sdk8_dir() -> Option<PathBuf> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v8.0";
|
|
||||||
let key = otry!(LOCAL_MACHINE.open(key.as_ref()).ok());
|
|
||||||
let root = otry!(key.query_str("InstallationFolder").ok());
|
|
||||||
Some(root.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
const PROCESSOR_ARCHITECTURE_INTEL: u16 = 0;
|
|
||||||
const PROCESSOR_ARCHITECTURE_AMD64: u16 = 9;
|
|
||||||
const X86: u16 = PROCESSOR_ARCHITECTURE_INTEL;
|
|
||||||
const X86_64: u16 = PROCESSOR_ARCHITECTURE_AMD64;
|
|
||||||
|
|
||||||
// When choosing the tool to use, we have to choose the one which matches
|
|
||||||
// the target architecture. Otherwise we end up in situations where someone
|
|
||||||
// on 32-bit Windows is trying to cross compile to 64-bit and it tries to
|
|
||||||
// invoke the native 64-bit compiler which won't work.
|
|
||||||
//
|
|
||||||
// For the return value of this function, the first member of the tuple is
|
|
||||||
// the folder of the tool we will be invoking, while the second member is
|
|
||||||
// the folder of the host toolchain for that tool which is essential when
|
|
||||||
// using a cross linker. We return a Vec since on x64 there are often two
|
|
||||||
// linkers that can target the architecture we desire. The 64-bit host
|
|
||||||
// linker is preferred, and hence first, due to 64-bit allowing it more
|
|
||||||
// address space to work with and potentially being faster.
|
|
||||||
fn bin_subdir(target: &str) -> Vec<(&'static str, &'static str)> {
|
|
||||||
let arch = target.split('-').next().unwrap();
|
|
||||||
match (arch, host_arch()) {
|
|
||||||
("i686", X86) => vec![("", "")],
|
|
||||||
("i686", X86_64) => vec![("amd64_x86", "amd64"), ("", "")],
|
|
||||||
("x86_64", X86) => vec![("x86_amd64", "")],
|
|
||||||
("x86_64", X86_64) => vec![("amd64", "amd64"), ("x86_amd64", "")],
|
|
||||||
("arm", X86) => vec![("x86_arm", "")],
|
|
||||||
("arm", X86_64) => vec![("amd64_arm", "amd64"), ("x86_arm", "")],
|
|
||||||
_ => vec![],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lib_subdir(target: &str) -> Option<&'static str> {
|
|
||||||
let arch = target.split('-').next().unwrap();
|
|
||||||
match arch {
|
|
||||||
"i686" => Some("x86"),
|
|
||||||
"x86_64" => Some("x64"),
|
|
||||||
"arm" => Some("arm"),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MSVC's x86 libraries are not in a subfolder
|
|
||||||
fn vc_lib_subdir(target: &str) -> Option<&'static str> {
|
|
||||||
let arch = target.split('-').next().unwrap();
|
|
||||||
match arch {
|
|
||||||
"i686" => Some(""),
|
|
||||||
"x86_64" => Some("amd64"),
|
|
||||||
"arm" => Some("arm"),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(bad_style)]
|
|
||||||
fn host_arch() -> u16 {
|
|
||||||
type DWORD = u32;
|
|
||||||
type WORD = u16;
|
|
||||||
type LPVOID = *mut u8;
|
|
||||||
type DWORD_PTR = usize;
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct SYSTEM_INFO {
|
|
||||||
wProcessorArchitecture: WORD,
|
|
||||||
_wReserved: WORD,
|
|
||||||
_dwPageSize: DWORD,
|
|
||||||
_lpMinimumApplicationAddress: LPVOID,
|
|
||||||
_lpMaximumApplicationAddress: LPVOID,
|
|
||||||
_dwActiveProcessorMask: DWORD_PTR,
|
|
||||||
_dwNumberOfProcessors: DWORD,
|
|
||||||
_dwProcessorType: DWORD,
|
|
||||||
_dwAllocationGranularity: DWORD,
|
|
||||||
_wProcessorLevel: WORD,
|
|
||||||
_wProcessorRevision: WORD,
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "system" {
|
|
||||||
fn GetNativeSystemInfo(lpSystemInfo: *mut SYSTEM_INFO);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
let mut info = mem::zeroed();
|
|
||||||
GetNativeSystemInfo(&mut info);
|
|
||||||
info.wProcessorArchitecture
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given a registry key, look at all the sub keys and find the one which has
|
|
||||||
// the maximal numeric value.
|
|
||||||
//
|
|
||||||
// Returns the name of the maximal key as well as the opened maximal key.
|
|
||||||
fn max_version(key: &RegistryKey) -> Option<(OsString, RegistryKey)> {
|
|
||||||
let mut max_vers = 0;
|
|
||||||
let mut max_key = None;
|
|
||||||
for subkey in key.iter().filter_map(|k| k.ok()) {
|
|
||||||
let val = subkey.to_str().and_then(|s| {
|
|
||||||
s.trim_left_matches("v").replace(".", "").parse().ok()
|
|
||||||
});
|
|
||||||
let val = match val {
|
|
||||||
Some(s) => s,
|
|
||||||
None => continue,
|
|
||||||
};
|
|
||||||
if val > max_vers {
|
|
||||||
if let Ok(k) = key.open(&subkey) {
|
|
||||||
max_vers = val;
|
|
||||||
max_key = Some((subkey, k));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return max_key
|
|
||||||
}
|
|
||||||
|
|
||||||
// see http://stackoverflow.com/questions/328017/path-to-msbuild
|
|
||||||
fn find_msbuild(target: &str) -> Option<Tool> {
|
|
||||||
let key = r"SOFTWARE\Microsoft\MSBuild\ToolsVersions";
|
|
||||||
LOCAL_MACHINE.open(key.as_ref()).ok().and_then(|key| {
|
|
||||||
max_version(&key).and_then(|(_vers, key)| {
|
|
||||||
key.query_str("MSBuildToolsPath").ok()
|
|
||||||
})
|
|
||||||
}).map(|path| {
|
|
||||||
let mut path = PathBuf::from(path);
|
|
||||||
path.push("MSBuild.exe");
|
|
||||||
let mut tool = Tool::new(path);
|
|
||||||
if target.contains("x86_64") {
|
|
||||||
tool.env.push(("Platform".into(), "X64".into()));
|
|
||||||
}
|
|
||||||
tool
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
49
third_party/rust/gcc/tests/cc_env.rs
vendored
49
third_party/rust/gcc/tests/cc_env.rs
vendored
|
|
@ -1,49 +0,0 @@
|
||||||
extern crate tempdir;
|
|
||||||
extern crate gcc;
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
mod support;
|
|
||||||
use support::Test;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn main() {
|
|
||||||
ccache();
|
|
||||||
distcc();
|
|
||||||
ccache_spaces();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ccache() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.shim("ccache");
|
|
||||||
|
|
||||||
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
|
|
||||||
test.gcc().file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0)
|
|
||||||
.must_have("lol-this-is-not-a-compiler foo")
|
|
||||||
.must_have("foo.c")
|
|
||||||
.must_not_have("ccache");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ccache_spaces() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.shim("ccache");
|
|
||||||
|
|
||||||
env::set_var("CC", "ccache lol-this-is-not-a-compiler foo");
|
|
||||||
test.gcc().file("foo.c").compile("libfoo.a");
|
|
||||||
test.cmd(0).must_have("lol-this-is-not-a-compiler foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
fn distcc() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.shim("distcc");
|
|
||||||
|
|
||||||
env::set_var("CC", "distcc lol-this-is-not-a-compiler foo");
|
|
||||||
test.gcc().file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0)
|
|
||||||
.must_have("lol-this-is-not-a-compiler foo")
|
|
||||||
.must_have("foo.c")
|
|
||||||
.must_not_have("distcc");
|
|
||||||
}
|
|
||||||
111
third_party/rust/gcc/tests/support/mod.rs
vendored
111
third_party/rust/gcc/tests/support/mod.rs
vendored
|
|
@ -1,111 +0,0 @@
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use std::env;
|
|
||||||
use std::ffi::OsStr;
|
|
||||||
use std::fs::{self, File};
|
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::path::PathBuf;
|
|
||||||
|
|
||||||
use gcc;
|
|
||||||
use tempdir::TempDir;
|
|
||||||
|
|
||||||
pub struct Test {
|
|
||||||
pub td: TempDir,
|
|
||||||
pub gcc: PathBuf,
|
|
||||||
pub msvc: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Execution {
|
|
||||||
args: Vec<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Test {
|
|
||||||
pub fn new() -> Test {
|
|
||||||
let mut gcc = PathBuf::from(env::current_exe().unwrap());
|
|
||||||
gcc.pop();
|
|
||||||
gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX));
|
|
||||||
Test {
|
|
||||||
td: TempDir::new("gcc-test").unwrap(),
|
|
||||||
gcc: gcc,
|
|
||||||
msvc: false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gnu() -> Test {
|
|
||||||
let t = Test::new();
|
|
||||||
t.shim("cc").shim("ar");
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn msvc() -> Test {
|
|
||||||
let mut t = Test::new();
|
|
||||||
t.shim("cl").shim("lib.exe");
|
|
||||||
t.msvc = true;
|
|
||||||
return t
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn shim(&self, name: &str) -> &Test {
|
|
||||||
let fname = format!("{}{}", name, env::consts::EXE_SUFFIX);
|
|
||||||
fs::hard_link(&self.gcc, self.td.path().join(&fname)).or_else(|_| {
|
|
||||||
fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ())
|
|
||||||
}).unwrap();
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn gcc(&self) -> gcc::Config {
|
|
||||||
let mut cfg = gcc::Config::new();
|
|
||||||
let mut path = env::split_paths(&env::var_os("PATH").unwrap())
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
path.insert(0, self.td.path().to_owned());
|
|
||||||
let target = if self.msvc {
|
|
||||||
"x86_64-pc-windows-msvc"
|
|
||||||
} else {
|
|
||||||
"x86_64-unknown-linux-gnu"
|
|
||||||
};
|
|
||||||
|
|
||||||
cfg.target(target).host(target)
|
|
||||||
.opt_level(2)
|
|
||||||
.debug(false)
|
|
||||||
.out_dir(self.td.path())
|
|
||||||
.__set_env("PATH", env::join_paths(path).unwrap())
|
|
||||||
.__set_env("GCCTEST_OUT_DIR", self.td.path());
|
|
||||||
if self.msvc {
|
|
||||||
cfg.compiler(self.td.path().join("cl"));
|
|
||||||
cfg.archiver(self.td.path().join("lib.exe"));
|
|
||||||
}
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cmd(&self, i: u32) -> Execution {
|
|
||||||
let mut s = String::new();
|
|
||||||
File::open(self.td.path().join(format!("out{}", i))).unwrap()
|
|
||||||
.read_to_string(&mut s).unwrap();
|
|
||||||
Execution {
|
|
||||||
args: s.lines().map(|s| s.to_string()).collect(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Execution {
|
|
||||||
pub fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
|
|
||||||
if !self.has(p.as_ref()) {
|
|
||||||
panic!("didn't find {:?} in {:?}", p.as_ref(), self.args);
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution {
|
|
||||||
if self.has(p.as_ref()) {
|
|
||||||
panic!("found {:?}", p.as_ref());
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn has(&self, p: &OsStr) -> bool {
|
|
||||||
self.args.iter().any(|arg| {
|
|
||||||
OsStr::new(arg) == p
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
193
third_party/rust/gcc/tests/test.rs
vendored
193
third_party/rust/gcc/tests/test.rs
vendored
|
|
@ -1,193 +0,0 @@
|
||||||
extern crate gcc;
|
|
||||||
extern crate tempdir;
|
|
||||||
|
|
||||||
use support::Test;
|
|
||||||
|
|
||||||
mod support;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_smoke() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-O2")
|
|
||||||
.must_have("foo.c")
|
|
||||||
.must_not_have("-g")
|
|
||||||
.must_have("-c")
|
|
||||||
.must_have("-ffunction-sections")
|
|
||||||
.must_have("-fdata-sections");
|
|
||||||
test.cmd(1).must_have(test.td.path().join("foo.o"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_opt_level_1() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.opt_level(1)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-O1")
|
|
||||||
.must_not_have("-O2");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_debug() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.debug(true)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
test.cmd(0).must_have("-g");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_x86_64() {
|
|
||||||
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
|
|
||||||
let target = format!("x86_64-{}", vendor);
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.target(&target)
|
|
||||||
.host(&target)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-fPIC")
|
|
||||||
.must_have("-m64");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_x86_64_no_pic() {
|
|
||||||
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
|
|
||||||
let target = format!("x86_64-{}", vendor);
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.pic(false)
|
|
||||||
.target(&target)
|
|
||||||
.host(&target)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_not_have("-fPIC");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_i686() {
|
|
||||||
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
|
|
||||||
let target = format!("i686-{}", vendor);
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.target(&target)
|
|
||||||
.host(&target)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_not_have("-fPIC")
|
|
||||||
.must_have("-m32");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_i686_pic() {
|
|
||||||
for vendor in &["unknown-linux-gnu", "apple-darwin"] {
|
|
||||||
let target = format!("i686-{}", vendor);
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.pic(true)
|
|
||||||
.target(&target)
|
|
||||||
.host(&target)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-fPIC");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_set_stdlib() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.cpp_set_stdlib(Some("foo"))
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_not_have("-stdlib=foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_include() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.include("foo/bar")
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-I").must_have("foo/bar");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_define() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.define("FOO", Some("bar"))
|
|
||||||
.define("BAR", None)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("-DFOO=bar").must_have("-DBAR");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn gnu_compile_assembly() {
|
|
||||||
let test = Test::gnu();
|
|
||||||
test.gcc()
|
|
||||||
.file("foo.S").compile("libfoo.a");
|
|
||||||
test.cmd(0).must_have("foo.S");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn msvc_smoke() {
|
|
||||||
let test = Test::msvc();
|
|
||||||
test.gcc()
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("/O2")
|
|
||||||
.must_have("foo.c")
|
|
||||||
.must_not_have("/Z7")
|
|
||||||
.must_have("/c");
|
|
||||||
test.cmd(1).must_have(test.td.path().join("foo.o"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn msvc_opt_level_0() {
|
|
||||||
let test = Test::msvc();
|
|
||||||
test.gcc()
|
|
||||||
.opt_level(0)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_not_have("/O2");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn msvc_debug() {
|
|
||||||
let test = Test::msvc();
|
|
||||||
test.gcc()
|
|
||||||
.debug(true)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
test.cmd(0).must_have("/Z7");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn msvc_include() {
|
|
||||||
let test = Test::msvc();
|
|
||||||
test.gcc()
|
|
||||||
.include("foo/bar")
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("/I").must_have("foo/bar");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn msvc_define() {
|
|
||||||
let test = Test::msvc();
|
|
||||||
test.gcc()
|
|
||||||
.define("FOO", Some("bar"))
|
|
||||||
.define("BAR", None)
|
|
||||||
.file("foo.c").compile("libfoo.a");
|
|
||||||
|
|
||||||
test.cmd(0).must_have("/DFOO=bar").must_have("/DBAR");
|
|
||||||
}
|
|
||||||
1
third_party/rust/idna/.cargo-checksum.json
vendored
1
third_party/rust/idna/.cargo-checksum.json
vendored
|
|
@ -1 +0,0 @@
|
||||||
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"d0aad6852ec947597bab20cd85ad15e014044cb7717c9a91f4b8da0081b7134d","src/IdnaMappingTable.txt":"5e9f5929130b713e698162ac5b60a99ccfb831606686b1c50777cd920b55dee2","src/lib.rs":"b8e85707a40e8472d2e90849a1e0e24a7442f3c4614a57a60125f87d11e985a4","src/make_uts46_mapping_table.py":"36fa77c443672f15872d60438f96b7302eae28ec506b60a892579debc79b8e39","src/punycode.rs":"df883ec00b35cab38f96992667eef0767d8587746bfdab0613a03e4c49a26c16","src/uts46.rs":"c879570c511f210565ac0dbce8a212be6503e62cd7ed698830804bb7729e98de","src/uts46_mapping_table.rs":"daa59e4b6399a738f73967b222b7dce6c9706a471d306330d77380c89089fa24","tests/IdnaTest.txt":"12e7e150b04a7a2cb1f9b72222174844342218807126e9dbc53069505a5f6000","tests/punycode.rs":"2f4086411c00b0641377afe81071e51a695110a0cce474287557738c07f74322","tests/punycode_tests.json":"3d4ac0cf25984c37b9ce197f5df680a0136f728fb8ec82bc76624e42139eb3a8","tests/tests.rs":"bb92e129dc5e17e9a86ec6062dd7b3f4c905c4af69e773d7c70efea177654c7b","tests/uts46.rs":"be9f928c60b88a8e277ddfb1769f09a8cd273e2e120e8450fb9b34f4dc852b37"},"package":"1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"}
|
|
||||||
0
third_party/rust/idna/.cargo-ok
vendored
0
third_party/rust/idna/.cargo-ok
vendored
24
third_party/rust/idna/Cargo.toml
vendored
24
third_party/rust/idna/Cargo.toml
vendored
|
|
@ -1,24 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "idna"
|
|
||||||
version = "0.1.0"
|
|
||||||
authors = ["Simon Sapin <simon.sapin@exyr.org>"]
|
|
||||||
description = "IDNA (Internationalizing Domain Names in Applications) and Punycode."
|
|
||||||
repository = "https://github.com/servo/rust-url/"
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
doctest = false
|
|
||||||
test = false
|
|
||||||
|
|
||||||
[[test]]
|
|
||||||
name = "tests"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
rustc-test = "0.1"
|
|
||||||
rustc-serialize = "0.3"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
unicode-bidi = "0.2.3"
|
|
||||||
unicode-normalization = "0.1.2"
|
|
||||||
matches = "0.1"
|
|
||||||
8190
third_party/rust/idna/src/IdnaMappingTable.txt
vendored
8190
third_party/rust/idna/src/IdnaMappingTable.txt
vendored
File diff suppressed because it is too large
Load diff
73
third_party/rust/idna/src/lib.rs
vendored
73
third_party/rust/idna/src/lib.rs
vendored
|
|
@ -1,73 +0,0 @@
|
||||||
// Copyright 2016 Simon Sapin.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
//! This Rust crate implements IDNA
|
|
||||||
//! [per the WHATWG URL Standard](https://url.spec.whatwg.org/#idna).
|
|
||||||
//!
|
|
||||||
//! It also exposes the underlying algorithms from [*Unicode IDNA Compatibility Processing*
|
|
||||||
//! (Unicode Technical Standard #46)](http://www.unicode.org/reports/tr46/)
|
|
||||||
//! and [Punycode (RFC 3492)](https://tools.ietf.org/html/rfc3492).
|
|
||||||
//!
|
|
||||||
//! Quoting from [UTS #46’s introduction](http://www.unicode.org/reports/tr46/#Introduction):
|
|
||||||
//!
|
|
||||||
//! > Initially, domain names were restricted to ASCII characters.
|
|
||||||
//! > A system was introduced in 2003 for internationalized domain names (IDN).
|
|
||||||
//! > This system is called Internationalizing Domain Names for Applications,
|
|
||||||
//! > or IDNA2003 for short.
|
|
||||||
//! > This mechanism supports IDNs by means of a client software transformation
|
|
||||||
//! > into a format known as Punycode.
|
|
||||||
//! > A revision of IDNA was approved in 2010 (IDNA2008).
|
|
||||||
//! > This revision has a number of incompatibilities with IDNA2003.
|
|
||||||
//! >
|
|
||||||
//! > The incompatibilities force implementers of client software,
|
|
||||||
//! > such as browsers and emailers,
|
|
||||||
//! > to face difficult choices during the transition period
|
|
||||||
//! > as registries shift from IDNA2003 to IDNA2008.
|
|
||||||
//! > This document specifies a mechanism
|
|
||||||
//! > that minimizes the impact of this transition for client software,
|
|
||||||
//! > allowing client software to access domains that are valid under either system.
|
|
||||||
|
|
||||||
#[macro_use] extern crate matches;
|
|
||||||
extern crate unicode_bidi;
|
|
||||||
extern crate unicode_normalization;
|
|
||||||
|
|
||||||
pub mod punycode;
|
|
||||||
pub mod uts46;
|
|
||||||
|
|
||||||
/// The [domain to ASCII](https://url.spec.whatwg.org/#concept-domain-to-ascii) algorithm.
|
|
||||||
///
|
|
||||||
/// Return the ASCII representation a domain name,
|
|
||||||
/// normalizing characters (upper-case to lower-case and other kinds of equivalence)
|
|
||||||
/// and using Punycode as necessary.
|
|
||||||
///
|
|
||||||
/// This process may fail.
|
|
||||||
pub fn domain_to_ascii(domain: &str) -> Result<String, uts46::Errors> {
|
|
||||||
uts46::to_ascii(domain, uts46::Flags {
|
|
||||||
use_std3_ascii_rules: false,
|
|
||||||
transitional_processing: true, // XXX: switch when Firefox does
|
|
||||||
verify_dns_length: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The [domain to Unicode](https://url.spec.whatwg.org/#concept-domain-to-unicode) algorithm.
|
|
||||||
///
|
|
||||||
/// Return the Unicode representation of a domain name,
|
|
||||||
/// normalizing characters (upper-case to lower-case and other kinds of equivalence)
|
|
||||||
/// and decoding Punycode as necessary.
|
|
||||||
///
|
|
||||||
/// This may indicate [syntax violations](https://url.spec.whatwg.org/#syntax-violation)
|
|
||||||
/// but always returns a string for the mapped domain.
|
|
||||||
pub fn domain_to_unicode(domain: &str) -> (String, Result<(), uts46::Errors>) {
|
|
||||||
uts46::to_unicode(domain, uts46::Flags {
|
|
||||||
use_std3_ascii_rules: false,
|
|
||||||
|
|
||||||
// Unused:
|
|
||||||
transitional_processing: true,
|
|
||||||
verify_dns_length: false,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
# Copyright 2013-2014 Valentin Gosu.
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
# Run as: python make_uts46_mapping_table.py IdnaMappingTable.txt > uts46_mapping_table.rs
|
|
||||||
# You can get the latest idna table from
|
|
||||||
# http://www.unicode.org/Public/idna/latest/IdnaMappingTable.txt
|
|
||||||
|
|
||||||
print('''\
|
|
||||||
// Copyright 2013-2014 Valentin Gosu.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
// Generated by make_idna_table.py
|
|
||||||
|
|
||||||
static TABLE: &'static [Range] = &[
|
|
||||||
''')
|
|
||||||
|
|
||||||
txt = open("IdnaMappingTable.txt")
|
|
||||||
|
|
||||||
def char(s):
|
|
||||||
return (unichr(int(s, 16))
|
|
||||||
.encode('utf8')
|
|
||||||
.replace('\\', '\\\\')
|
|
||||||
.replace('"', '\\"')
|
|
||||||
.replace('\0', '\\0'))
|
|
||||||
|
|
||||||
for line in txt:
|
|
||||||
# remove comments
|
|
||||||
line, _, _ = line.partition('#')
|
|
||||||
# skip empty lines
|
|
||||||
if len(line.strip()) == 0:
|
|
||||||
continue
|
|
||||||
fields = line.split(';')
|
|
||||||
if fields[0].strip() == 'D800..DFFF':
|
|
||||||
continue # Surrogates don't occur in Rust strings.
|
|
||||||
first, _, last = fields[0].strip().partition('..')
|
|
||||||
if not last:
|
|
||||||
last = first
|
|
||||||
mapping = fields[1].strip().replace('_', ' ').title().replace(' ', '')
|
|
||||||
if len(fields) > 2:
|
|
||||||
if fields[2].strip():
|
|
||||||
mapping += '("%s")' % ''.join(char(c) for c in fields[2].strip().split(' '))
|
|
||||||
elif mapping == "Deviation":
|
|
||||||
mapping += '("")'
|
|
||||||
print(" Range { from: '%s', to: '%s', mapping: %s }," % (char(first), char(last), mapping))
|
|
||||||
|
|
||||||
print("];")
|
|
||||||
213
third_party/rust/idna/src/punycode.rs
vendored
213
third_party/rust/idna/src/punycode.rs
vendored
|
|
@ -1,213 +0,0 @@
|
||||||
// Copyright 2013 Simon Sapin.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
//! Punycode ([RFC 3492](http://tools.ietf.org/html/rfc3492)) implementation.
|
|
||||||
//!
|
|
||||||
//! Since Punycode fundamentally works on unicode code points,
|
|
||||||
//! `encode` and `decode` take and return slices and vectors of `char`.
|
|
||||||
//! `encode_str` and `decode_to_string` provide convenience wrappers
|
|
||||||
//! that convert from and to Rust’s UTF-8 based `str` and `String` types.
|
|
||||||
|
|
||||||
use std::u32;
|
|
||||||
use std::char;
|
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
|
|
||||||
// Bootstring parameters for Punycode
|
|
||||||
static BASE: u32 = 36;
|
|
||||||
static T_MIN: u32 = 1;
|
|
||||||
static T_MAX: u32 = 26;
|
|
||||||
static SKEW: u32 = 38;
|
|
||||||
static DAMP: u32 = 700;
|
|
||||||
static INITIAL_BIAS: u32 = 72;
|
|
||||||
static INITIAL_N: u32 = 0x80;
|
|
||||||
static DELIMITER: char = '-';
|
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn adapt(mut delta: u32, num_points: u32, first_time: bool) -> u32 {
|
|
||||||
delta /= if first_time { DAMP } else { 2 };
|
|
||||||
delta += delta / num_points;
|
|
||||||
let mut k = 0;
|
|
||||||
while delta > ((BASE - T_MIN) * T_MAX) / 2 {
|
|
||||||
delta /= BASE - T_MIN;
|
|
||||||
k += BASE;
|
|
||||||
}
|
|
||||||
k + (((BASE - T_MIN + 1) * delta) / (delta + SKEW))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert Punycode to an Unicode `String`.
|
|
||||||
///
|
|
||||||
/// This is a convenience wrapper around `decode`.
|
|
||||||
#[inline]
|
|
||||||
pub fn decode_to_string(input: &str) -> Option<String> {
|
|
||||||
decode(input).map(|chars| chars.into_iter().collect())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert Punycode to Unicode.
|
|
||||||
///
|
|
||||||
/// Return None on malformed input or overflow.
|
|
||||||
/// Overflow can only happen on inputs that take more than
|
|
||||||
/// 63 encoded bytes, the DNS limit on domain name labels.
|
|
||||||
pub fn decode(input: &str) -> Option<Vec<char>> {
|
|
||||||
// Handle "basic" (ASCII) code points.
|
|
||||||
// They are encoded as-is before the last delimiter, if any.
|
|
||||||
let (mut output, input) = match input.rfind(DELIMITER) {
|
|
||||||
None => (Vec::new(), input),
|
|
||||||
Some(position) => (
|
|
||||||
input[..position].chars().collect(),
|
|
||||||
if position > 0 { &input[position + 1..] } else { input }
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let mut code_point = INITIAL_N;
|
|
||||||
let mut bias = INITIAL_BIAS;
|
|
||||||
let mut i = 0;
|
|
||||||
let mut iter = input.bytes();
|
|
||||||
loop {
|
|
||||||
let previous_i = i;
|
|
||||||
let mut weight = 1;
|
|
||||||
let mut k = BASE;
|
|
||||||
let mut byte = match iter.next() {
|
|
||||||
None => break,
|
|
||||||
Some(byte) => byte,
|
|
||||||
};
|
|
||||||
// Decode a generalized variable-length integer into delta,
|
|
||||||
// which gets added to i.
|
|
||||||
loop {
|
|
||||||
let digit = match byte {
|
|
||||||
byte @ b'0' ... b'9' => byte - b'0' + 26,
|
|
||||||
byte @ b'A' ... b'Z' => byte - b'A',
|
|
||||||
byte @ b'a' ... b'z' => byte - b'a',
|
|
||||||
_ => return None
|
|
||||||
} as u32;
|
|
||||||
if digit > (u32::MAX - i) / weight {
|
|
||||||
return None // Overflow
|
|
||||||
}
|
|
||||||
i += digit * weight;
|
|
||||||
let t = if k <= bias { T_MIN }
|
|
||||||
else if k >= bias + T_MAX { T_MAX }
|
|
||||||
else { k - bias };
|
|
||||||
if digit < t {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if weight > u32::MAX / (BASE - t) {
|
|
||||||
return None // Overflow
|
|
||||||
}
|
|
||||||
weight *= BASE - t;
|
|
||||||
k += BASE;
|
|
||||||
byte = match iter.next() {
|
|
||||||
None => return None, // End of input before the end of this delta
|
|
||||||
Some(byte) => byte,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
let length = output.len() as u32;
|
|
||||||
bias = adapt(i - previous_i, length + 1, previous_i == 0);
|
|
||||||
if i / (length + 1) > u32::MAX - code_point {
|
|
||||||
return None // Overflow
|
|
||||||
}
|
|
||||||
// i was supposed to wrap around from length+1 to 0,
|
|
||||||
// incrementing code_point each time.
|
|
||||||
code_point += i / (length + 1);
|
|
||||||
i %= length + 1;
|
|
||||||
let c = match char::from_u32(code_point) {
|
|
||||||
Some(c) => c,
|
|
||||||
None => return None
|
|
||||||
};
|
|
||||||
output.insert(i as usize, c);
|
|
||||||
i += 1;
|
|
||||||
}
|
|
||||||
Some(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert an Unicode `str` to Punycode.
|
|
||||||
///
|
|
||||||
/// This is a convenience wrapper around `encode`.
|
|
||||||
#[inline]
|
|
||||||
pub fn encode_str(input: &str) -> Option<String> {
|
|
||||||
encode(&input.chars().collect::<Vec<char>>())
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Convert Unicode to Punycode.
|
|
||||||
///
|
|
||||||
/// Return None on overflow, which can only happen on inputs that would take more than
|
|
||||||
/// 63 encoded bytes, the DNS limit on domain name labels.
|
|
||||||
pub fn encode(input: &[char]) -> Option<String> {
|
|
||||||
// Handle "basic" (ASCII) code points. They are encoded as-is.
|
|
||||||
let output_bytes = input.iter().filter_map(|&c|
|
|
||||||
if c.is_ascii() { Some(c as u8) } else { None }
|
|
||||||
).collect();
|
|
||||||
let mut output = unsafe { String::from_utf8_unchecked(output_bytes) };
|
|
||||||
let basic_length = output.len() as u32;
|
|
||||||
if basic_length > 0 {
|
|
||||||
output.push_str("-")
|
|
||||||
}
|
|
||||||
let mut code_point = INITIAL_N;
|
|
||||||
let mut delta = 0;
|
|
||||||
let mut bias = INITIAL_BIAS;
|
|
||||||
let mut processed = basic_length;
|
|
||||||
let input_length = input.len() as u32;
|
|
||||||
while processed < input_length {
|
|
||||||
// All code points < code_point have been handled already.
|
|
||||||
// Find the next larger one.
|
|
||||||
let min_code_point = input.iter().map(|&c| c as u32)
|
|
||||||
.filter(|&c| c >= code_point).min().unwrap();
|
|
||||||
if min_code_point - code_point > (u32::MAX - delta) / (processed + 1) {
|
|
||||||
return None // Overflow
|
|
||||||
}
|
|
||||||
// Increase delta to advance the decoder’s <code_point,i> state to <min_code_point,0>
|
|
||||||
delta += (min_code_point - code_point) * (processed + 1);
|
|
||||||
code_point = min_code_point;
|
|
||||||
for &c in input {
|
|
||||||
let c = c as u32;
|
|
||||||
if c < code_point {
|
|
||||||
delta += 1;
|
|
||||||
if delta == 0 {
|
|
||||||
return None // Overflow
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if c == code_point {
|
|
||||||
// Represent delta as a generalized variable-length integer:
|
|
||||||
let mut q = delta;
|
|
||||||
let mut k = BASE;
|
|
||||||
loop {
|
|
||||||
let t = if k <= bias { T_MIN }
|
|
||||||
else if k >= bias + T_MAX { T_MAX }
|
|
||||||
else { k - bias };
|
|
||||||
if q < t {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
let value = t + ((q - t) % (BASE - t));
|
|
||||||
value_to_digit(value, &mut output);
|
|
||||||
q = (q - t) / (BASE - t);
|
|
||||||
k += BASE;
|
|
||||||
}
|
|
||||||
value_to_digit(q, &mut output);
|
|
||||||
bias = adapt(delta, processed + 1, processed == basic_length);
|
|
||||||
delta = 0;
|
|
||||||
processed += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delta += 1;
|
|
||||||
code_point += 1;
|
|
||||||
}
|
|
||||||
Some(output)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn value_to_digit(value: u32, output: &mut String) {
|
|
||||||
let code_point = match value {
|
|
||||||
0 ... 25 => value + 0x61, // a..z
|
|
||||||
26 ... 35 => value - 26 + 0x30, // 0..9
|
|
||||||
_ => panic!()
|
|
||||||
};
|
|
||||||
unsafe { output.as_mut_vec().push(code_point as u8) }
|
|
||||||
}
|
|
||||||
322
third_party/rust/idna/src/uts46.rs
vendored
322
third_party/rust/idna/src/uts46.rs
vendored
|
|
@ -1,322 +0,0 @@
|
||||||
// Copyright 2013-2014 Valentin Gosu.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
//! [*Unicode IDNA Compatibility Processing*
|
|
||||||
//! (Unicode Technical Standard #46)](http://www.unicode.org/reports/tr46/)
|
|
||||||
|
|
||||||
use self::Mapping::*;
|
|
||||||
use punycode;
|
|
||||||
use std::ascii::AsciiExt;
|
|
||||||
use unicode_normalization::UnicodeNormalization;
|
|
||||||
use unicode_normalization::char::is_combining_mark;
|
|
||||||
use unicode_bidi::{BidiClass, bidi_class};
|
|
||||||
|
|
||||||
include!("uts46_mapping_table.rs");
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
enum Mapping {
|
|
||||||
Valid,
|
|
||||||
Ignored,
|
|
||||||
Mapped(&'static str),
|
|
||||||
Deviation(&'static str),
|
|
||||||
Disallowed,
|
|
||||||
DisallowedStd3Valid,
|
|
||||||
DisallowedStd3Mapped(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Range {
|
|
||||||
from: char,
|
|
||||||
to: char,
|
|
||||||
mapping: Mapping,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn find_char(codepoint: char) -> &'static Mapping {
|
|
||||||
let mut min = 0;
|
|
||||||
let mut max = TABLE.len() - 1;
|
|
||||||
while max > min {
|
|
||||||
let mid = (min + max) >> 1;
|
|
||||||
if codepoint > TABLE[mid].to {
|
|
||||||
min = mid;
|
|
||||||
} else if codepoint < TABLE[mid].from {
|
|
||||||
max = mid;
|
|
||||||
} else {
|
|
||||||
min = mid;
|
|
||||||
max = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&TABLE[min].mapping
|
|
||||||
}
|
|
||||||
|
|
||||||
fn map_char(codepoint: char, flags: Flags, output: &mut String, errors: &mut Vec<Error>) {
|
|
||||||
match *find_char(codepoint) {
|
|
||||||
Mapping::Valid => output.push(codepoint),
|
|
||||||
Mapping::Ignored => {},
|
|
||||||
Mapping::Mapped(mapping) => output.push_str(mapping),
|
|
||||||
Mapping::Deviation(mapping) => {
|
|
||||||
if flags.transitional_processing {
|
|
||||||
output.push_str(mapping)
|
|
||||||
} else {
|
|
||||||
output.push(codepoint)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Mapping::Disallowed => {
|
|
||||||
errors.push(Error::DissallowedCharacter);
|
|
||||||
output.push(codepoint);
|
|
||||||
}
|
|
||||||
Mapping::DisallowedStd3Valid => {
|
|
||||||
if flags.use_std3_ascii_rules {
|
|
||||||
errors.push(Error::DissallowedByStd3AsciiRules);
|
|
||||||
}
|
|
||||||
output.push(codepoint)
|
|
||||||
}
|
|
||||||
Mapping::DisallowedStd3Mapped(mapping) => {
|
|
||||||
if flags.use_std3_ascii_rules {
|
|
||||||
errors.push(Error::DissallowedMappedInStd3);
|
|
||||||
}
|
|
||||||
output.push_str(mapping)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://tools.ietf.org/html/rfc5893#section-2
|
|
||||||
fn passes_bidi(label: &str, transitional_processing: bool) -> bool {
|
|
||||||
let mut chars = label.chars();
|
|
||||||
let class = match chars.next() {
|
|
||||||
Some(c) => bidi_class(c),
|
|
||||||
None => return true, // empty string
|
|
||||||
};
|
|
||||||
|
|
||||||
if class == BidiClass::L
|
|
||||||
|| (class == BidiClass::ON && transitional_processing) // starts with \u200D
|
|
||||||
|| (class == BidiClass::ES && transitional_processing) // hack: 1.35.+33.49
|
|
||||||
|| class == BidiClass::EN // hack: starts with number 0à.\u05D0
|
|
||||||
{ // LTR
|
|
||||||
// Rule 5
|
|
||||||
loop {
|
|
||||||
match chars.next() {
|
|
||||||
Some(c) => {
|
|
||||||
let c = bidi_class(c);
|
|
||||||
if !matches!(c, BidiClass::L | BidiClass::EN |
|
|
||||||
BidiClass::ES | BidiClass::CS |
|
|
||||||
BidiClass::ET | BidiClass::ON |
|
|
||||||
BidiClass::BN | BidiClass::NSM) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => { break; },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rule 6
|
|
||||||
let mut rev_chars = label.chars().rev();
|
|
||||||
let mut last = rev_chars.next();
|
|
||||||
loop { // must end in L or EN followed by 0 or more NSM
|
|
||||||
match last {
|
|
||||||
Some(c) if bidi_class(c) == BidiClass::NSM => {
|
|
||||||
last = rev_chars.next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_ => { break; },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: does not pass for àˇ.\u05D0
|
|
||||||
// match last {
|
|
||||||
// Some(c) if bidi_class(c) == BidiClass::L
|
|
||||||
// || bidi_class(c) == BidiClass::EN => {},
|
|
||||||
// Some(c) => { return false; },
|
|
||||||
// _ => {}
|
|
||||||
// }
|
|
||||||
|
|
||||||
} else if class == BidiClass::R || class == BidiClass::AL { // RTL
|
|
||||||
let mut found_en = false;
|
|
||||||
let mut found_an = false;
|
|
||||||
|
|
||||||
// Rule 2
|
|
||||||
loop {
|
|
||||||
match chars.next() {
|
|
||||||
Some(c) => {
|
|
||||||
let char_class = bidi_class(c);
|
|
||||||
|
|
||||||
if char_class == BidiClass::EN {
|
|
||||||
found_en = true;
|
|
||||||
}
|
|
||||||
if char_class == BidiClass::AN {
|
|
||||||
found_an = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !matches!(char_class, BidiClass::R | BidiClass::AL |
|
|
||||||
BidiClass::AN | BidiClass::EN |
|
|
||||||
BidiClass::ES | BidiClass::CS |
|
|
||||||
BidiClass::ET | BidiClass::ON |
|
|
||||||
BidiClass::BN | BidiClass::NSM) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => { break; },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Rule 3
|
|
||||||
let mut rev_chars = label.chars().rev();
|
|
||||||
let mut last = rev_chars.next();
|
|
||||||
loop { // must end in L or EN followed by 0 or more NSM
|
|
||||||
match last {
|
|
||||||
Some(c) if bidi_class(c) == BidiClass::NSM => {
|
|
||||||
last = rev_chars.next();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_ => { break; },
|
|
||||||
}
|
|
||||||
}
|
|
||||||
match last {
|
|
||||||
Some(c) if matches!(bidi_class(c), BidiClass::R | BidiClass::AL |
|
|
||||||
BidiClass::EN | BidiClass::AN) => {},
|
|
||||||
_ => { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// Rule 4
|
|
||||||
if found_an && found_en {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Rule 2: Should start with L or R/AL
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// http://www.unicode.org/reports/tr46/#Validity_Criteria
|
|
||||||
fn validate(label: &str, flags: Flags, errors: &mut Vec<Error>) {
|
|
||||||
if label.nfc().ne(label.chars()) {
|
|
||||||
errors.push(Error::ValidityCriteria);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can not contain '.' since the input is from .split('.')
|
|
||||||
if {
|
|
||||||
let mut chars = label.chars().skip(2);
|
|
||||||
let third = chars.next();
|
|
||||||
let fourth = chars.next();
|
|
||||||
(third, fourth) == (Some('-'), Some('-'))
|
|
||||||
} || label.starts_with("-")
|
|
||||||
|| label.ends_with("-")
|
|
||||||
|| label.chars().next().map_or(false, is_combining_mark)
|
|
||||||
|| label.chars().any(|c| match *find_char(c) {
|
|
||||||
Mapping::Valid => false,
|
|
||||||
Mapping::Deviation(_) => flags.transitional_processing,
|
|
||||||
Mapping::DisallowedStd3Valid => flags.use_std3_ascii_rules,
|
|
||||||
_ => true,
|
|
||||||
})
|
|
||||||
|| !passes_bidi(label, flags.transitional_processing)
|
|
||||||
{
|
|
||||||
errors.push(Error::ValidityCriteria)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// http://www.unicode.org/reports/tr46/#Processing
|
|
||||||
fn processing(domain: &str, flags: Flags, errors: &mut Vec<Error>) -> String {
|
|
||||||
let mut mapped = String::new();
|
|
||||||
for c in domain.chars() {
|
|
||||||
map_char(c, flags, &mut mapped, errors)
|
|
||||||
}
|
|
||||||
let normalized: String = mapped.nfc().collect();
|
|
||||||
let mut validated = String::new();
|
|
||||||
for label in normalized.split('.') {
|
|
||||||
if validated.len() > 0 {
|
|
||||||
validated.push('.');
|
|
||||||
}
|
|
||||||
if label.starts_with("xn--") {
|
|
||||||
match punycode::decode_to_string(&label["xn--".len()..]) {
|
|
||||||
Some(decoded_label) => {
|
|
||||||
let flags = Flags { transitional_processing: false, ..flags };
|
|
||||||
validate(&decoded_label, flags, errors);
|
|
||||||
validated.push_str(&decoded_label)
|
|
||||||
}
|
|
||||||
None => errors.push(Error::PunycodeError)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
validate(label, flags, errors);
|
|
||||||
validated.push_str(label)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
validated
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct Flags {
|
|
||||||
pub use_std3_ascii_rules: bool,
|
|
||||||
pub transitional_processing: bool,
|
|
||||||
pub verify_dns_length: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
|
|
||||||
enum Error {
|
|
||||||
PunycodeError,
|
|
||||||
ValidityCriteria,
|
|
||||||
DissallowedByStd3AsciiRules,
|
|
||||||
DissallowedMappedInStd3,
|
|
||||||
DissallowedCharacter,
|
|
||||||
TooLongForDns,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Errors recorded during UTS #46 processing.
|
|
||||||
///
|
|
||||||
/// This is opaque for now, only indicating the precense of at least one error.
|
|
||||||
/// More details may be exposed in the future.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct Errors(Vec<Error>);
|
|
||||||
|
|
||||||
/// http://www.unicode.org/reports/tr46/#ToASCII
|
|
||||||
pub fn to_ascii(domain: &str, flags: Flags) -> Result<String, Errors> {
|
|
||||||
let mut errors = Vec::new();
|
|
||||||
let mut result = String::new();
|
|
||||||
for label in processing(domain, flags, &mut errors).split('.') {
|
|
||||||
if result.len() > 0 {
|
|
||||||
result.push('.');
|
|
||||||
}
|
|
||||||
if label.is_ascii() {
|
|
||||||
result.push_str(label);
|
|
||||||
} else {
|
|
||||||
match punycode::encode_str(label) {
|
|
||||||
Some(x) => {
|
|
||||||
result.push_str("xn--");
|
|
||||||
result.push_str(&x);
|
|
||||||
},
|
|
||||||
None => errors.push(Error::PunycodeError)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if flags.verify_dns_length {
|
|
||||||
let domain = if result.ends_with(".") { &result[..result.len()-1] } else { &*result };
|
|
||||||
if domain.len() < 1 || domain.len() > 253 ||
|
|
||||||
domain.split('.').any(|label| label.len() < 1 || label.len() > 63) {
|
|
||||||
errors.push(Error::TooLongForDns)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if errors.is_empty() {
|
|
||||||
Ok(result)
|
|
||||||
} else {
|
|
||||||
Err(Errors(errors))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// http://www.unicode.org/reports/tr46/#ToUnicode
|
|
||||||
///
|
|
||||||
/// Only `use_std3_ascii_rules` is used in `flags`.
|
|
||||||
pub fn to_unicode(domain: &str, mut flags: Flags) -> (String, Result<(), Errors>) {
|
|
||||||
flags.transitional_processing = false;
|
|
||||||
let mut errors = Vec::new();
|
|
||||||
let domain = processing(domain, flags, &mut errors);
|
|
||||||
let errors = if errors.is_empty() {
|
|
||||||
Ok(())
|
|
||||||
} else {
|
|
||||||
Err(Errors(errors))
|
|
||||||
};
|
|
||||||
(domain, errors)
|
|
||||||
}
|
|
||||||
8191
third_party/rust/idna/src/uts46_mapping_table.rs
vendored
8191
third_party/rust/idna/src/uts46_mapping_table.rs
vendored
File diff suppressed because it is too large
Load diff
5097
third_party/rust/idna/tests/IdnaTest.txt
vendored
5097
third_party/rust/idna/tests/IdnaTest.txt
vendored
File diff suppressed because it is too large
Load diff
65
third_party/rust/idna/tests/punycode.rs
vendored
65
third_party/rust/idna/tests/punycode.rs
vendored
|
|
@ -1,65 +0,0 @@
|
||||||
// Copyright 2013 Simon Sapin.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
use idna::punycode::{decode, encode_str};
|
|
||||||
use rustc_serialize::json::{Json, Object};
|
|
||||||
use test::TestFn;
|
|
||||||
|
|
||||||
fn one_test(decoded: &str, encoded: &str) {
|
|
||||||
match decode(encoded) {
|
|
||||||
None => panic!("Decoding {} failed.", encoded),
|
|
||||||
Some(result) => {
|
|
||||||
let result = result.into_iter().collect::<String>();
|
|
||||||
assert!(result == decoded,
|
|
||||||
format!("Incorrect decoding of \"{}\":\n \"{}\"\n!= \"{}\"\n",
|
|
||||||
encoded, result, decoded))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
match encode_str(decoded) {
|
|
||||||
None => panic!("Encoding {} failed.", decoded),
|
|
||||||
Some(result) => {
|
|
||||||
assert!(result == encoded,
|
|
||||||
format!("Incorrect encoding of \"{}\":\n \"{}\"\n!= \"{}\"\n",
|
|
||||||
decoded, result, encoded))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_string<'a>(map: &'a Object, key: &str) -> &'a str {
|
|
||||||
match map.get(&key.to_string()) {
|
|
||||||
Some(&Json::String(ref s)) => s,
|
|
||||||
None => "",
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn collect_tests<F: FnMut(String, TestFn)>(add_test: &mut F) {
|
|
||||||
match Json::from_str(include_str!("punycode_tests.json")) {
|
|
||||||
Ok(Json::Array(tests)) => for (i, test) in tests.into_iter().enumerate() {
|
|
||||||
match test {
|
|
||||||
Json::Object(o) => {
|
|
||||||
let test_name = {
|
|
||||||
let desc = get_string(&o, "description");
|
|
||||||
if desc.is_empty() {
|
|
||||||
format!("Punycode {}", i + 1)
|
|
||||||
} else {
|
|
||||||
format!("Punycode {}: {}", i + 1, desc)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
add_test(test_name, TestFn::dyn_test_fn(move || one_test(
|
|
||||||
get_string(&o, "decoded"),
|
|
||||||
get_string(&o, "encoded"),
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
other => panic!("{:?}", other)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
120
third_party/rust/idna/tests/punycode_tests.json
vendored
120
third_party/rust/idna/tests/punycode_tests.json
vendored
|
|
@ -1,120 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"description": "These tests are copied from https://github.com/bestiejs/punycode.js/blob/master/tests/tests.js , used under the MIT license.",
|
|
||||||
"decoded": "",
|
|
||||||
"encoded": ""
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "a single basic code point",
|
|
||||||
"decoded": "Bach",
|
|
||||||
"encoded": "Bach-"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "a single non-ASCII character",
|
|
||||||
"decoded": "\u00FC",
|
|
||||||
"encoded": "tda"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "multiple non-ASCII characters",
|
|
||||||
"decoded": "\u00FC\u00EB\u00E4\u00F6\u2665",
|
|
||||||
"encoded": "4can8av2009b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "mix of ASCII and non-ASCII characters",
|
|
||||||
"decoded": "b\u00FCcher",
|
|
||||||
"encoded": "bcher-kva"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "long string with both ASCII and non-ASCII characters",
|
|
||||||
"decoded": "Willst du die Bl\u00FCthe des fr\u00FChen, die Fr\u00FCchte des sp\u00E4teren Jahres",
|
|
||||||
"encoded": "Willst du die Blthe des frhen, die Frchte des spteren Jahres-x9e96lkal"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Arabic (Egyptian)",
|
|
||||||
"decoded": "\u0644\u064A\u0647\u0645\u0627\u0628\u062A\u0643\u0644\u0645\u0648\u0634\u0639\u0631\u0628\u064A\u061F",
|
|
||||||
"encoded": "egbpdaj6bu4bxfgehfvwxn"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Chinese (simplified)",
|
|
||||||
"decoded": "\u4ED6\u4EEC\u4E3A\u4EC0\u4E48\u4E0D\u8BF4\u4E2d\u6587",
|
|
||||||
"encoded": "ihqwcrb4cv8a8dqg056pqjye"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Chinese (traditional)",
|
|
||||||
"decoded": "\u4ED6\u5011\u7232\u4EC0\u9EBD\u4E0D\u8AAA\u4E2D\u6587",
|
|
||||||
"encoded": "ihqwctvzc91f659drss3x8bo0yb"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Czech",
|
|
||||||
"decoded": "Pro\u010Dprost\u011Bnemluv\u00ED\u010Desky",
|
|
||||||
"encoded": "Proprostnemluvesky-uyb24dma41a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Hebrew",
|
|
||||||
"decoded": "\u05DC\u05DE\u05D4\u05D4\u05DD\u05E4\u05E9\u05D5\u05D8\u05DC\u05D0\u05DE\u05D3\u05D1\u05E8\u05D9\u05DD\u05E2\u05D1\u05E8\u05D9\u05EA",
|
|
||||||
"encoded": "4dbcagdahymbxekheh6e0a7fei0b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Hindi (Devanagari)",
|
|
||||||
"decoded": "\u092F\u0939\u0932\u094B\u0917\u0939\u093F\u0928\u094D\u0926\u0940\u0915\u094D\u092F\u094B\u0902\u0928\u0939\u0940\u0902\u092C\u094B\u0932\u0938\u0915\u0924\u0947\u0939\u0948\u0902",
|
|
||||||
"encoded": "i1baa7eci9glrd9b2ae1bj0hfcgg6iyaf8o0a1dig0cd"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Japanese (kanji and hiragana)",
|
|
||||||
"decoded": "\u306A\u305C\u307F\u3093\u306A\u65E5\u672C\u8A9E\u3092\u8A71\u3057\u3066\u304F\u308C\u306A\u3044\u306E\u304B",
|
|
||||||
"encoded": "n8jok5ay5dzabd5bym9f0cm5685rrjetr6pdxa"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Korean (Hangul syllables)",
|
|
||||||
"decoded": "\uC138\uACC4\uC758\uBAA8\uB4E0\uC0AC\uB78C\uB4E4\uC774\uD55C\uAD6D\uC5B4\uB97C\uC774\uD574\uD55C\uB2E4\uBA74\uC5BC\uB9C8\uB098\uC88B\uC744\uAE4C",
|
|
||||||
"encoded": "989aomsvi5e83db1d2a355cv1e0vak1dwrv93d5xbh15a0dt30a5jpsd879ccm6fea98c"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Russian (Cyrillic)",
|
|
||||||
"decoded": "\u043F\u043E\u0447\u0435\u043C\u0443\u0436\u0435\u043E\u043D\u0438\u043D\u0435\u0433\u043E\u0432\u043E\u0440\u044F\u0442\u043F\u043E\u0440\u0443\u0441\u0441\u043A\u0438",
|
|
||||||
"encoded": "b1abfaaepdrnnbgefbadotcwatmq2g4l"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Spanish",
|
|
||||||
"decoded": "Porqu\u00E9nopuedensimplementehablarenEspa\u00F1ol",
|
|
||||||
"encoded": "PorqunopuedensimplementehablarenEspaol-fmd56a"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "Vietnamese",
|
|
||||||
"decoded": "T\u1EA1isaoh\u1ECDkh\u00F4ngth\u1EC3ch\u1EC9n\u00F3iti\u1EBFngVi\u1EC7t",
|
|
||||||
"encoded": "TisaohkhngthchnitingVit-kjcr8268qyxafd2f1b9g"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "3\u5E74B\u7D44\u91D1\u516B\u5148\u751F",
|
|
||||||
"encoded": "3B-ww4c5e180e575a65lsy2b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "\u5B89\u5BA4\u5948\u7F8E\u6075-with-SUPER-MONKEYS",
|
|
||||||
"encoded": "-with-SUPER-MONKEYS-pc58ag80a8qai00g7n9n"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "Hello-Another-Way-\u305D\u308C\u305E\u308C\u306E\u5834\u6240",
|
|
||||||
"encoded": "Hello-Another-Way--fc4qua05auwb3674vfr0b"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "\u3072\u3068\u3064\u5C4B\u6839\u306E\u4E0B2",
|
|
||||||
"encoded": "2-u9tlzr9756bt3uc0v"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "Maji\u3067Koi\u3059\u308B5\u79D2\u524D",
|
|
||||||
"encoded": "MajiKoi5-783gue6qz075azm5e"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "\u30D1\u30D5\u30A3\u30FCde\u30EB\u30F3\u30D0",
|
|
||||||
"encoded": "de-jg4avhby1noc0d"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"decoded": "\u305D\u306E\u30B9\u30D4\u30FC\u30C9\u3067",
|
|
||||||
"encoded": "d9juau41awczczp"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"description": "ASCII string that breaks the existing rules for host-name labels (It's not a realistic example for IDNA, because IDNA never encodes pure ASCII labels.)",
|
|
||||||
"decoded": "-> $1.00 <-",
|
|
||||||
"encoded": "-> $1.00 <--"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
25
third_party/rust/idna/tests/tests.rs
vendored
25
third_party/rust/idna/tests/tests.rs
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
extern crate idna;
|
|
||||||
extern crate rustc_serialize;
|
|
||||||
extern crate test;
|
|
||||||
|
|
||||||
mod punycode;
|
|
||||||
mod uts46;
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
let mut tests = Vec::new();
|
|
||||||
{
|
|
||||||
let mut add_test = |name, run| {
|
|
||||||
tests.push(test::TestDescAndFn {
|
|
||||||
desc: test::TestDesc {
|
|
||||||
name: test::DynTestName(name),
|
|
||||||
ignore: false,
|
|
||||||
should_panic: test::ShouldPanic::No,
|
|
||||||
},
|
|
||||||
testfn: run,
|
|
||||||
})
|
|
||||||
};
|
|
||||||
punycode::collect_tests(&mut add_test);
|
|
||||||
uts46::collect_tests(&mut add_test);
|
|
||||||
}
|
|
||||||
test::test_main(&std::env::args().collect::<Vec<_>>(), tests)
|
|
||||||
}
|
|
||||||
117
third_party/rust/idna/tests/uts46.rs
vendored
117
third_party/rust/idna/tests/uts46.rs
vendored
|
|
@ -1,117 +0,0 @@
|
||||||
// Copyright 2013-2014 Valentin Gosu.
|
|
||||||
//
|
|
||||||
// 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.
|
|
||||||
|
|
||||||
use std::char;
|
|
||||||
use idna::uts46;
|
|
||||||
use test::TestFn;
|
|
||||||
|
|
||||||
pub fn collect_tests<F: FnMut(String, TestFn)>(add_test: &mut F) {
|
|
||||||
// http://www.unicode.org/Public/idna/latest/IdnaTest.txt
|
|
||||||
for (i, line) in include_str!("IdnaTest.txt").lines().enumerate() {
|
|
||||||
if line == "" || line.starts_with("#") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
// Remove comments
|
|
||||||
let mut line = match line.find("#") {
|
|
||||||
Some(index) => &line[0..index],
|
|
||||||
None => line
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut expected_failure = false;
|
|
||||||
if line.starts_with("XFAIL") {
|
|
||||||
expected_failure = true;
|
|
||||||
line = &line[5..line.len()];
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut pieces = line.split(';').map(|x| x.trim()).collect::<Vec<&str>>();
|
|
||||||
|
|
||||||
let test_type = pieces.remove(0);
|
|
||||||
let original = pieces.remove(0);
|
|
||||||
let source = unescape(original);
|
|
||||||
let to_unicode = pieces.remove(0);
|
|
||||||
let to_ascii = pieces.remove(0);
|
|
||||||
let nv8 = if pieces.len() > 0 { pieces.remove(0) } else { "" };
|
|
||||||
|
|
||||||
if expected_failure {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let test_name = format!("UTS #46 line {}", i + 1);
|
|
||||||
add_test(test_name, TestFn::dyn_test_fn(move || {
|
|
||||||
let result = uts46::to_ascii(&source, uts46::Flags {
|
|
||||||
use_std3_ascii_rules: true,
|
|
||||||
transitional_processing: test_type == "T",
|
|
||||||
verify_dns_length: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
if to_ascii.starts_with("[") {
|
|
||||||
if to_ascii.starts_with("[C") {
|
|
||||||
// http://unicode.org/reports/tr46/#Deviations
|
|
||||||
// applications that perform IDNA2008 lookup are not required to check
|
|
||||||
// for these contexts
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let res = result.ok();
|
|
||||||
assert!(res == None, "Expected error. result: {} | original: {} | source: {}",
|
|
||||||
res.unwrap(), original, source);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let to_ascii = if to_ascii.len() > 0 {
|
|
||||||
to_ascii.to_string()
|
|
||||||
} else {
|
|
||||||
if to_unicode.len() > 0 {
|
|
||||||
to_unicode.to_string()
|
|
||||||
} else {
|
|
||||||
source.clone()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if nv8 == "NV8" {
|
|
||||||
// This result isn't valid under IDNA2008. Skip it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert!(result.is_ok(), "Couldn't parse {} | original: {} | error: {:?}",
|
|
||||||
source, original, result.err());
|
|
||||||
let output = result.ok().unwrap();
|
|
||||||
assert!(output == to_ascii, "result: {} | expected: {} | original: {} | source: {}",
|
|
||||||
output, to_ascii, original, source);
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unescape(input: &str) -> String {
|
|
||||||
let mut output = String::new();
|
|
||||||
let mut chars = input.chars();
|
|
||||||
loop {
|
|
||||||
match chars.next() {
|
|
||||||
None => return output,
|
|
||||||
Some(c) =>
|
|
||||||
if c == '\\' {
|
|
||||||
match chars.next().unwrap() {
|
|
||||||
'\\' => output.push('\\'),
|
|
||||||
'u' => {
|
|
||||||
let c1 = chars.next().unwrap().to_digit(16).unwrap();
|
|
||||||
let c2 = chars.next().unwrap().to_digit(16).unwrap();
|
|
||||||
let c3 = chars.next().unwrap().to_digit(16).unwrap();
|
|
||||||
let c4 = chars.next().unwrap().to_digit(16).unwrap();
|
|
||||||
match char::from_u32((((c1 * 16 + c2) * 16 + c3) * 16 + c4))
|
|
||||||
{
|
|
||||||
Some(c) => output.push(c),
|
|
||||||
None => { output.push_str(&format!("\\u{:X}{:X}{:X}{:X}",c1,c2,c3,c4)); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
_ => panic!("Invalid test data input"),
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
output.push(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1
third_party/rust/libc/.cargo-checksum.json
vendored
1
third_party/rust/libc/.cargo-checksum.json
vendored
File diff suppressed because one or more lines are too long
0
third_party/rust/libc/.cargo-ok
vendored
0
third_party/rust/libc/.cargo-ok
vendored
3
third_party/rust/libc/.gitignore
vendored
3
third_party/rust/libc/.gitignore
vendored
|
|
@ -1,3 +0,0 @@
|
||||||
target
|
|
||||||
Cargo.lock
|
|
||||||
*~
|
|
||||||
119
third_party/rust/libc/.travis.yml
vendored
119
third_party/rust/libc/.travis.yml
vendored
|
|
@ -1,119 +0,0 @@
|
||||||
language: rust
|
|
||||||
sudo: required
|
|
||||||
dist: trusty
|
|
||||||
services:
|
|
||||||
- docker
|
|
||||||
install:
|
|
||||||
- curl https://static.rust-lang.org/rustup.sh |
|
|
||||||
sh -s -- --add-target=$TARGET --disable-sudo -y --prefix=`rustc --print sysroot`
|
|
||||||
script:
|
|
||||||
- cargo build
|
|
||||||
- cargo build --no-default-features
|
|
||||||
- cargo generate-lockfile --manifest-path libc-test/Cargo.toml
|
|
||||||
- if [[ $TRAVIS_OS_NAME = "linux" ]]; then
|
|
||||||
sh ci/run-docker.sh $TARGET;
|
|
||||||
else
|
|
||||||
export CARGO_TARGET_DIR=`pwd`/target;
|
|
||||||
sh ci/run.sh $TARGET;
|
|
||||||
fi
|
|
||||||
- rustc ci/style.rs && ./style src
|
|
||||||
osx_image: xcode7.3
|
|
||||||
env:
|
|
||||||
global:
|
|
||||||
secure: eIDEoQdTyglcsTD13zSGotAX2HDhRSXIaaTnVZTThqLSrySOc3/6KY3qmOc2Msf7XaBqfFy9QA+alk7OwfePp253eiy1Kced67ffjjFOytEcRT7FlQiYpcYQD6WNHZEj62/bJBO4LTM9sGtWNCTJVEDKW0WM8mUK7qNuC+honPM=
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
# 1.0.0 compat
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
|
||||||
rust: 1.0.0
|
|
||||||
script: cargo build
|
|
||||||
install:
|
|
||||||
|
|
||||||
# build documentation
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
script: sh ci/dox.sh
|
|
||||||
|
|
||||||
# stable compat
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=i686-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=x86_64-apple-darwin
|
|
||||||
rust: stable
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=i686-apple-darwin
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=arm-linux-androideabi
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-musl
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=i686-unknown-linux-musl
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=arm-unknown-linux-gnueabihf
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=aarch64-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=i386-apple-ios
|
|
||||||
rust: stable
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=x86_64-apple-ios
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-rumprun-netbsd
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=powerpc-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=powerpc64-unknown-linux-gnu
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=mipsel-unknown-linux-musl
|
|
||||||
rust: stable
|
|
||||||
|
|
||||||
# beta
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
|
||||||
rust: beta
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=x86_64-apple-darwin
|
|
||||||
rust: beta
|
|
||||||
|
|
||||||
# nightly
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-linux-gnu
|
|
||||||
rust: nightly
|
|
||||||
- os: osx
|
|
||||||
env: TARGET=x86_64-apple-darwin
|
|
||||||
rust: nightly
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=mips-unknown-linux-gnu
|
|
||||||
# not sure why this has to be nightly...
|
|
||||||
rust: nightly
|
|
||||||
|
|
||||||
# QEMU based targets that compile in an emulator
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-freebsd
|
|
||||||
rust: stable
|
|
||||||
- os: linux
|
|
||||||
env: TARGET=x86_64-unknown-openbsd QEMU=openbsd.qcow2
|
|
||||||
rust: stable
|
|
||||||
script: sh ci/run-docker.sh $TARGET
|
|
||||||
install:
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
webhooks: https://buildbot.rust-lang.org/homu/travis
|
|
||||||
18
third_party/rust/libc/Cargo.toml
vendored
18
third_party/rust/libc/Cargo.toml
vendored
|
|
@ -1,18 +0,0 @@
|
||||||
[package]
|
|
||||||
|
|
||||||
name = "libc"
|
|
||||||
version = "0.2.16"
|
|
||||||
authors = ["The Rust Project Developers"]
|
|
||||||
license = "MIT/Apache-2.0"
|
|
||||||
readme = "README.md"
|
|
||||||
repository = "https://github.com/rust-lang/libc"
|
|
||||||
homepage = "https://github.com/rust-lang/libc"
|
|
||||||
documentation = "http://doc.rust-lang.org/libc"
|
|
||||||
description = """
|
|
||||||
A library for types and bindings to native C functions often found in libc or
|
|
||||||
other common platform libraries.
|
|
||||||
"""
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["use_std"]
|
|
||||||
use_std = []
|
|
||||||
201
third_party/rust/libc/LICENSE-APACHE
vendored
201
third_party/rust/libc/LICENSE-APACHE
vendored
|
|
@ -1,201 +0,0 @@
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
25
third_party/rust/libc/LICENSE-MIT
vendored
25
third_party/rust/libc/LICENSE-MIT
vendored
|
|
@ -1,25 +0,0 @@
|
||||||
Copyright (c) 2014 The Rust Project Developers
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any
|
|
||||||
person obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without
|
|
||||||
limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software
|
|
||||||
is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice
|
|
||||||
shall be included in all copies or substantial portions
|
|
||||||
of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
||||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
||||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
135
third_party/rust/libc/README.md
vendored
135
third_party/rust/libc/README.md
vendored
|
|
@ -1,135 +0,0 @@
|
||||||
libc
|
|
||||||
====
|
|
||||||
|
|
||||||
A Rust library with native bindings to the types and functions commonly found on
|
|
||||||
various systems, including libc.
|
|
||||||
|
|
||||||
[](https://travis-ci.org/rust-lang/libc)
|
|
||||||
[](https://ci.appveyor.com/project/alexcrichton/libc)
|
|
||||||
|
|
||||||
[Documentation](#platforms-and-documentation)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
First, add the following to your `Cargo.toml`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
libc = "0.2"
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, add this to your crate root:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
extern crate libc;
|
|
||||||
```
|
|
||||||
|
|
||||||
Currently libc by default links to the standard library, but if you would
|
|
||||||
instead like to use libc in a `#![no_std]` situation or crate you can request
|
|
||||||
this via:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
libc = { version = "0.2", default-features = false }
|
|
||||||
```
|
|
||||||
|
|
||||||
## What is libc?
|
|
||||||
|
|
||||||
The primary purpose of this crate is to provide all of the definitions necessary
|
|
||||||
to easily interoperate with C code (or "C-like" code) on each of the platforms
|
|
||||||
that Rust supports. This includes type definitions (e.g. `c_int`), constants
|
|
||||||
(e.g. `EINVAL`) as well as function headers (e.g. `malloc`).
|
|
||||||
|
|
||||||
This crate does not strive to have any form of compatibility across platforms,
|
|
||||||
but rather it is simply a straight binding to the system libraries on the
|
|
||||||
platform in question.
|
|
||||||
|
|
||||||
## Public API
|
|
||||||
|
|
||||||
This crate exports all underlying platform types, functions, and constants under
|
|
||||||
the crate root, so all items are accessible as `libc::foo`. The types and values
|
|
||||||
of all the exported APIs match the platform that libc is compiled for.
|
|
||||||
|
|
||||||
More detailed information about the design of this library can be found in its
|
|
||||||
[associated RFC][rfc].
|
|
||||||
|
|
||||||
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1291-promote-libc.md
|
|
||||||
|
|
||||||
## Adding an API
|
|
||||||
|
|
||||||
Want to use an API which currently isn't bound in `libc`? It's quite easy to add
|
|
||||||
one!
|
|
||||||
|
|
||||||
The internal structure of this crate is designed to minimize the number of
|
|
||||||
`#[cfg]` attributes in order to easily be able to add new items which apply
|
|
||||||
to all platforms in the future. As a result, the crate is organized
|
|
||||||
hierarchically based on platform. Each module has a number of `#[cfg]`'d
|
|
||||||
children, but only one is ever actually compiled. Each module then reexports all
|
|
||||||
the contents of its children.
|
|
||||||
|
|
||||||
This means that for each platform that libc supports, the path from a
|
|
||||||
leaf module to the root will contain all bindings for the platform in question.
|
|
||||||
Consequently, this indicates where an API should be added! Adding an API at a
|
|
||||||
particular level in the hierarchy means that it is supported on all the child
|
|
||||||
platforms of that level. For example, when adding a Unix API it should be added
|
|
||||||
to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to
|
|
||||||
`src/unix/notbsd/linux/mod.rs`.
|
|
||||||
|
|
||||||
If you're not 100% sure at what level of the hierarchy an API should be added
|
|
||||||
at, fear not! This crate has CI support which tests any binding against all
|
|
||||||
platforms supported, so you'll see failures if an API is added at the wrong
|
|
||||||
level or has different signatures across platforms.
|
|
||||||
|
|
||||||
With that in mind, the steps for adding a new API are:
|
|
||||||
|
|
||||||
1. Determine where in the module hierarchy your API should be added.
|
|
||||||
2. Add the API.
|
|
||||||
3. Send a PR to this repo.
|
|
||||||
4. Wait for CI to pass, fixing errors.
|
|
||||||
5. Wait for a merge!
|
|
||||||
|
|
||||||
### Test before you commit
|
|
||||||
|
|
||||||
We have two automated tests running on [Travis](https://travis-ci.org/rust-lang/libc):
|
|
||||||
|
|
||||||
1. [`libc-test`](https://github.com/alexcrichton/ctest)
|
|
||||||
- `cd libc-test && cargo run`
|
|
||||||
- Use the `skip_*()` functions in `build.rs` if you really need a workaround.
|
|
||||||
2. Style checker
|
|
||||||
- `rustc ci/style.rs && ./style src`
|
|
||||||
|
|
||||||
## Platforms and Documentation
|
|
||||||
|
|
||||||
The following platforms are currently tested and have documentation available:
|
|
||||||
|
|
||||||
Tested:
|
|
||||||
* [`i686-pc-windows-msvc`](https://doc.rust-lang.org/libc/i686-pc-windows-msvc/libc/)
|
|
||||||
* [`x86_64-pc-windows-msvc`](https://doc.rust-lang.org/libc/x86_64-pc-windows-msvc/libc/)
|
|
||||||
(Windows)
|
|
||||||
* [`i686-pc-windows-gnu`](https://doc.rust-lang.org/libc/i686-pc-windows-gnu/libc/)
|
|
||||||
* [`x86_64-pc-windows-gnu`](https://doc.rust-lang.org/libc/x86_64-pc-windows-gnu/libc/)
|
|
||||||
* [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/)
|
|
||||||
* [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/)
|
|
||||||
(OSX)
|
|
||||||
* `i686-apple-ios`
|
|
||||||
* `x86_64-apple-ios`
|
|
||||||
* [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/)
|
|
||||||
* [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/)
|
|
||||||
(Linux)
|
|
||||||
* [`x86_64-unknown-linux-musl`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-musl/libc/)
|
|
||||||
(Linux MUSL)
|
|
||||||
* [`aarch64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/aarch64-unknown-linux-gnu/libc/)
|
|
||||||
* [`mips-unknown-linux-gnu`](https://doc.rust-lang.org/libc/mips-unknown-linux-gnu/libc/)
|
|
||||||
* [`arm-unknown-linux-gnueabihf`](https://doc.rust-lang.org/libc/arm-unknown-linux-gnueabihf/libc/)
|
|
||||||
* [`arm-linux-androideabi`](https://doc.rust-lang.org/libc/arm-linux-androideabi/libc/)
|
|
||||||
(Android)
|
|
||||||
* [`x86_64-unknown-freebsd`](https://doc.rust-lang.org/libc/x86_64-unknown-freebsd/libc/)
|
|
||||||
* [`x86_64-unknown-openbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-openbsd/libc/)
|
|
||||||
* [`x86_64-rumprun-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/)
|
|
||||||
|
|
||||||
The following may be supported, but are not guaranteed to always work:
|
|
||||||
|
|
||||||
* `i686-unknown-freebsd`
|
|
||||||
* [`x86_64-unknown-bitrig`](https://doc.rust-lang.org/libc/x86_64-unknown-bitrig/libc/)
|
|
||||||
* [`x86_64-unknown-dragonfly`](https://doc.rust-lang.org/libc/x86_64-unknown-dragonfly/libc/)
|
|
||||||
* [`x86_64-unknown-netbsd`](https://doc.rust-lang.org/libc/x86_64-unknown-netbsd/libc/)
|
|
||||||
21
third_party/rust/libc/appveyor.yml
vendored
21
third_party/rust/libc/appveyor.yml
vendored
|
|
@ -1,21 +0,0 @@
|
||||||
environment:
|
|
||||||
matrix:
|
|
||||||
- TARGET: x86_64-pc-windows-gnu
|
|
||||||
MSYS2_BITS: 64
|
|
||||||
- TARGET: i686-pc-windows-gnu
|
|
||||||
MSYS2_BITS: 32
|
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
|
||||||
- TARGET: i686-pc-windows-msvc
|
|
||||||
install:
|
|
||||||
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
|
||||||
- rustup-init.exe -y --default-host %TARGET%
|
|
||||||
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
|
||||||
- if defined MSYS2_BITS set PATH=%PATH%;C:\msys64\mingw%MSYS2_BITS%\bin
|
|
||||||
- rustc -V
|
|
||||||
- cargo -V
|
|
||||||
|
|
||||||
build: false
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- cargo test
|
|
||||||
- cargo run --manifest-path libc-test/Cargo.toml
|
|
||||||
203
third_party/rust/libc/ci/README.md
vendored
203
third_party/rust/libc/ci/README.md
vendored
|
|
@ -1,203 +0,0 @@
|
||||||
The goal of the libc crate is to have CI running everywhere to have the
|
|
||||||
strongest guarantees about the definitions that this library contains, and as a
|
|
||||||
result the CI is pretty complicated and also pretty large! Hopefully this can
|
|
||||||
serve as a guide through the sea of scripts in this directory and elsewhere in
|
|
||||||
this project.
|
|
||||||
|
|
||||||
# Files
|
|
||||||
|
|
||||||
First up, let's talk about the files in this directory:
|
|
||||||
|
|
||||||
* `run-travis.sh` - a shell script run by all Travis builders, this is
|
|
||||||
responsible for setting up the rest of the environment such as installing new
|
|
||||||
packages, downloading Rust target libraries, etc.
|
|
||||||
|
|
||||||
* `run.sh` - the actual script which runs tests for a particular architecture.
|
|
||||||
Called from the `run-travis.sh` script this will run all tests for the target
|
|
||||||
specified.
|
|
||||||
|
|
||||||
* `cargo-config` - Cargo configuration of linkers to use copied into place by
|
|
||||||
the `run-travis.sh` script before builds are run.
|
|
||||||
|
|
||||||
* `dox.sh` - script called from `run-travis.sh` on only the linux 64-bit nightly
|
|
||||||
Travis bots to build documentation for this crate.
|
|
||||||
|
|
||||||
* `landing-page-*.html` - used by `dox.sh` to generate a landing page for all
|
|
||||||
architectures' documentation.
|
|
||||||
|
|
||||||
* `run-qemu.sh` - see discussion about QEMU below
|
|
||||||
|
|
||||||
* `mips`, `rumprun` - instructions to build the docker image for each respective
|
|
||||||
CI target
|
|
||||||
|
|
||||||
# CI Systems
|
|
||||||
|
|
||||||
Currently this repository leverages a combination of Travis CI and AppVeyor for
|
|
||||||
running tests. The triples tested are:
|
|
||||||
|
|
||||||
* AppVeyor
|
|
||||||
* `{i686,x86_64}-pc-windows-{msvc,gnu}`
|
|
||||||
* Travis
|
|
||||||
* `{i686,x86_64,mips,aarch64}-unknown-linux-gnu`
|
|
||||||
* `x86_64-unknown-linux-musl`
|
|
||||||
* `arm-unknown-linux-gnueabihf`
|
|
||||||
* `arm-linux-androideabi`
|
|
||||||
* `{i686,x86_64}-apple-{darwin,ios}`
|
|
||||||
* `x86_64-rumprun-netbsd`
|
|
||||||
* `x86_64-unknown-freebsd`
|
|
||||||
* `x86_64-unknown-openbsd`
|
|
||||||
|
|
||||||
The Windows triples are all pretty standard, they just set up their environment
|
|
||||||
then run tests, no need for downloading any extra target libs (we just download
|
|
||||||
the right installer). The Intel Linux/OSX builds are similar in that we just
|
|
||||||
download the right target libs and run tests. Note that the Intel Linux/OSX
|
|
||||||
builds are run on stable/beta/nightly, but are the only ones that do so.
|
|
||||||
|
|
||||||
The remaining architectures look like:
|
|
||||||
|
|
||||||
* Android runs in a [docker image][android-docker] with an emulator, the NDK,
|
|
||||||
and the SDK already set up. The entire build happens within the docker image.
|
|
||||||
* The MIPS, ARM, and AArch64 builds all use the QEMU userspace emulator to run
|
|
||||||
the generated binary to actually verify the tests pass.
|
|
||||||
* The MUSL build just has to download a MUSL compiler and target libraries and
|
|
||||||
then otherwise runs tests normally.
|
|
||||||
* iOS builds need an extra linker flag currently, but beyond that they're built
|
|
||||||
as standard as everything else.
|
|
||||||
* The rumprun target builds an entire kernel from the test suite and then runs
|
|
||||||
it inside QEMU using the serial console to test whether it succeeded or
|
|
||||||
failed.
|
|
||||||
* The BSD builds, currently OpenBSD and FreeBSD, use QEMU to boot up a system
|
|
||||||
and compile/run tests. More information on that below.
|
|
||||||
|
|
||||||
[android-docker]: https://github.com/rust-lang/rust-buildbot/blob/master/slaves/android/Dockerfile
|
|
||||||
|
|
||||||
## QEMU
|
|
||||||
|
|
||||||
Lots of the architectures tested here use QEMU in the tests, so it's worth going
|
|
||||||
over all the crazy capabilities QEMU has and the various flavors in which we use
|
|
||||||
it!
|
|
||||||
|
|
||||||
First up, QEMU has userspace emulation where it doesn't boot a full kernel, it
|
|
||||||
just runs a binary from another architecture (using the `qemu-<arch>` wrappers).
|
|
||||||
We provide it the runtime path for the dynamically loaded system libraries,
|
|
||||||
however. This strategy is used for all Linux architectures that aren't intel.
|
|
||||||
Note that one downside of this QEMU system is that threads are barely
|
|
||||||
implemented, so we're careful to not spawn many threads.
|
|
||||||
|
|
||||||
For the rumprun target the only output is a kernel image, so we just use that
|
|
||||||
plus the `rumpbake` command to create a full kernel image which is then run from
|
|
||||||
within QEMU.
|
|
||||||
|
|
||||||
Finally, the fun part, the BSDs. Quite a few hoops are jumped through to get CI
|
|
||||||
working for these platforms, but the gist of it looks like:
|
|
||||||
|
|
||||||
* Cross compiling from Linux to any of the BSDs seems to be quite non-standard.
|
|
||||||
We may be able to get it working but it might be difficult at that point to
|
|
||||||
ensure that the libc definitions align with what you'd get on the BSD itself.
|
|
||||||
As a result, we try to do compiles within the BSD distro.
|
|
||||||
* On Travis we can't run a VM-in-a-VM, so we resort to userspace emulation
|
|
||||||
(QEMU).
|
|
||||||
* Unfortunately on Travis we also can't use KVM, so the emulation is super slow.
|
|
||||||
|
|
||||||
With all that in mind, the way BSD is tested looks like:
|
|
||||||
|
|
||||||
1. Download a pre-prepared image for the OS being tested.
|
|
||||||
2. Generate the tests for the OS being tested. This involves running the `ctest`
|
|
||||||
library over libc to generate a Rust file and a C file which will then be
|
|
||||||
compiled into the final test.
|
|
||||||
3. Generate a disk image which will later be mounted by the OS being tested.
|
|
||||||
This image is mostly just the libc directory, but some modifications are made
|
|
||||||
to compile the generated files from step 2.
|
|
||||||
4. The kernel is booted in QEMU, and it is configured to detect the libc-test
|
|
||||||
image being available, run the test script, and then shut down afterwards.
|
|
||||||
5. Look for whether the tests passed in the serial console output of the kernel.
|
|
||||||
|
|
||||||
There's some pretty specific instructions for setting up each image (detailed
|
|
||||||
below), but the main gist of this is that we must avoid a vanilla `cargo run`
|
|
||||||
inside of the `libc-test` directory (which is what it's intended for) because
|
|
||||||
that would compile `syntex_syntax`, a large library, with userspace emulation.
|
|
||||||
This invariably times out on Travis, so we can't do that.
|
|
||||||
|
|
||||||
Once all those hoops are jumped through, however, we can be happy that we're
|
|
||||||
testing almost everything!
|
|
||||||
|
|
||||||
Below are some details of how to set up the initial OS images which are
|
|
||||||
downloaded. Each image must be enabled have input/output over the serial
|
|
||||||
console, log in automatically at the serial console, detect if a second drive in
|
|
||||||
QEMU is available, and if so mount it, run a script (it'll specifically be
|
|
||||||
`run-qemu.sh` in this folder which is copied into the generated image talked
|
|
||||||
about above), and then shut down.
|
|
||||||
|
|
||||||
### QEMU setup - FreeBSD
|
|
||||||
|
|
||||||
1. Download CD installer (most minimal is fine)
|
|
||||||
2. `qemu-img create -f qcow2 foo.qcow2 2G`
|
|
||||||
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
|
|
||||||
4. run installer
|
|
||||||
5. `echo 'console="comconsole"' >> /boot/loader.conf`
|
|
||||||
6. `echo 'autoboot_delay="0"' >> /boot/loader.conf`
|
|
||||||
7. look at /etc/ttys, see what getty argument is for ttyu0
|
|
||||||
8. edit /etc/gettytab, look for ttyu0 argument, prepend `:al=root` to line
|
|
||||||
beneath
|
|
||||||
|
|
||||||
(note that the current image has a `freebsd` user, but this isn't really
|
|
||||||
necessary)
|
|
||||||
|
|
||||||
Once that's done, arrange for this script to run at login:
|
|
||||||
|
|
||||||
```
|
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
sudo kldload ext2fs
|
|
||||||
[ -e /dev/vtbd1 ] || exit 0
|
|
||||||
sudo mount -t ext2fs /dev/vtbd1 /mnt
|
|
||||||
sh /mnt/run.sh /mnt
|
|
||||||
sudo poweroff
|
|
||||||
```
|
|
||||||
|
|
||||||
Helpful links
|
|
||||||
|
|
||||||
* https://en.wikibooks.org/wiki/QEMU/Images
|
|
||||||
* https://blog.nekoconeko.nl/blog/2015/06/04/creating-an-openstack-freebsd-image.html
|
|
||||||
* https://www.freebsd.org/doc/handbook/serialconsole-setup.html
|
|
||||||
|
|
||||||
|
|
||||||
### QEMU setup - OpenBSD
|
|
||||||
|
|
||||||
1. Download CD installer
|
|
||||||
2. `qemu-img create -f qcow2 foo.qcow2 2G`
|
|
||||||
3. `qemu -cdrom foo.iso -drive if=virtio,file=foo.qcow2 -net nic,model=virtio -net user`
|
|
||||||
4. run installer
|
|
||||||
5. `echo 'set tty com0' >> /etc/boot.conf`
|
|
||||||
6. `echo 'boot' >> /etc/boot.conf`
|
|
||||||
7. Modify /etc/ttys, change the `tty00` at the end from 'unknown off' to
|
|
||||||
'vt220 on secure'
|
|
||||||
8. Modify same line in /etc/ttys to have `"/root/foo.sh"` as the shell
|
|
||||||
9. Add this script to `/root/foo.sh`
|
|
||||||
|
|
||||||
```
|
|
||||||
#!/bin/sh
|
|
||||||
exec 1>/dev/tty00
|
|
||||||
exec 2>&1
|
|
||||||
|
|
||||||
if mount -t ext2fs /dev/sd1c /mnt; then
|
|
||||||
sh /mnt/run.sh /mnt
|
|
||||||
shutdown -ph now
|
|
||||||
fi
|
|
||||||
|
|
||||||
# limited shell...
|
|
||||||
exec /bin/sh < /dev/tty00
|
|
||||||
```
|
|
||||||
|
|
||||||
10. `chmod +x /root/foo.sh`
|
|
||||||
|
|
||||||
Helpful links:
|
|
||||||
|
|
||||||
* https://en.wikibooks.org/wiki/QEMU/Images
|
|
||||||
* http://www.openbsd.org/faq/faq7.html#SerCon
|
|
||||||
|
|
||||||
# Questions?
|
|
||||||
|
|
||||||
Hopefully that's at least somewhat of an introduction to everything going on
|
|
||||||
here, and feel free to ping @alexcrichton with questions!
|
|
||||||
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
FROM ubuntu:14.04
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev ca-certificates \
|
|
||||||
gcc-aarch64-linux-gnu libc6-dev-arm64-cross qemu-user
|
|
||||||
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
FROM alexcrichton/rust-slave-android:2015-11-22
|
|
||||||
ENV CARGO_TARGET_ARM_LINUX_ANDROIDEABI_LINKER=arm-linux-androideabi-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
ENTRYPOINT ["sh"]
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev ca-certificates \
|
|
||||||
gcc-arm-linux-gnueabihf libc6-dev-armhf-cross qemu-user
|
|
||||||
ENV CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER=arm-linux-gnueabihf-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc-multilib libc6-dev ca-certificates
|
|
||||||
ENV PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc make libc6-dev git curl ca-certificates
|
|
||||||
RUN curl https://www.musl-libc.org/releases/musl-1.1.14.tar.gz | \
|
|
||||||
tar xzf - && \
|
|
||||||
cd musl-1.1.14 && \
|
|
||||||
CFLAGS=-m32 ./configure --prefix=/musl-i686 --disable-shared --target=i686 && \
|
|
||||||
make install -j4 && \
|
|
||||||
cd .. && \
|
|
||||||
rm -rf musl-1.1.14
|
|
||||||
ENV PATH=$PATH:/musl-i686/bin:/rust/bin
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev qemu-user ca-certificates \
|
|
||||||
gcc-mips-linux-gnu libc6-dev-mips-cross \
|
|
||||||
qemu-system-mips
|
|
||||||
|
|
||||||
ENV CARGO_TARGET_MIPS_UNKNOWN_LINUX_GNU_LINKER=mips-linux-gnu-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev qemu-user ca-certificates qemu-system-mips curl \
|
|
||||||
bzip2
|
|
||||||
|
|
||||||
RUN mkdir /toolchain
|
|
||||||
RUN curl -L https://downloads.openwrt.org/snapshots/trunk/malta/generic/OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 | \
|
|
||||||
tar xjf - -C /toolchain --strip-components=2
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/rust/bin:/toolchain/bin \
|
|
||||||
CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \
|
|
||||||
CARGO_TARGET_MIPSEL_UNKNOWN_LINUX_MUSL_LINKER=mipsel-openwrt-linux-gcc
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev qemu-user ca-certificates \
|
|
||||||
gcc-powerpc-linux-gnu libc6-dev-powerpc-cross \
|
|
||||||
qemu-system-ppc
|
|
||||||
|
|
||||||
ENV CARGO_TARGET_POWERPC_UNKNOWN_LINUX_GNU_LINKER=powerpc-linux-gnu-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
FROM ubuntu:16.04
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
gcc libc6-dev qemu-user ca-certificates \
|
|
||||||
gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross \
|
|
||||||
qemu-system-ppc
|
|
||||||
|
|
||||||
ENV CARGO_TARGET_POWERPC64_UNKNOWN_LINUX_GNU_LINKER=powerpc64-linux-gnu-gcc \
|
|
||||||
CC=powerpc64-linux-gnu-gcc \
|
|
||||||
PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
FROM mato/rumprun-toolchain-hw-x86_64
|
|
||||||
USER root
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
qemu
|
|
||||||
ENV PATH=$PATH:/rust/bin
|
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
FROM alexcrichton/rust-slave-linux-cross:2016-04-15
|
|
||||||
USER root
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends \
|
|
||||||
qemu qemu-kvm kmod cpu-checker
|
|
||||||
|
|
||||||
ENTRYPOINT ["sh"]
|
|
||||||
|
|
||||||
ENV PATH=$PATH:/rust/bin \
|
|
||||||
QEMU=freebsd.qcow2 \
|
|
||||||
CAN_CROSS=1 \
|
|
||||||
CARGO_TARGET_X86_64_UNKNOWN_FREEBSD_LINKER=x86_64-unknown-freebsd10-gcc
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue