mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +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)
|
||||
|
||||
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
|
||||
|
||||
|
||||
@template
|
||||
def RustLibrary(name):
|
||||
'''Template for Rust libraries.'''
|
||||
Library(name)
|
||||
|
||||
IS_RUST_LIBRARY = True
|
||||
|
||||
|
||||
@template
|
||||
def SharedLibrary(name):
|
||||
'''Template for shared libraries.'''
|
||||
|
|
|
|||
|
|
@ -905,44 +905,6 @@ $(ASOBJS):
|
|||
$(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS)
|
||||
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):
|
||||
$(REPORT_BUILD)
|
||||
$(AS) -o $@ $(DEFINES) $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) -c $<
|
||||
|
|
|
|||
|
|
@ -35,10 +35,6 @@ if CONFIG['MOZ_WEBM_ENCODER']:
|
|||
'TestWebMWriter.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_RUST']:
|
||||
UNIFIED_SOURCES += ['TestRust.cpp',]
|
||||
|
||||
|
||||
TEST_HARNESS_FILES.gtest += [
|
||||
'../test/gizmo-frag.mp4',
|
||||
'../test/gizmo.mp4',
|
||||
|
|
|
|||
|
|
@ -37,13 +37,4 @@ TEST_HARNESS_FILES.gtest += [
|
|||
'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'
|
||||
|
|
|
|||
|
|
@ -80,11 +80,6 @@ SOURCES += [
|
|||
'system/core/libutils/VectorImpl.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_RUST']:
|
||||
EXPORTS += [
|
||||
'binding/include/mp4parse.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'binding/Adts.cpp',
|
||||
'binding/AnnexB.cpp',
|
||||
|
|
|
|||
|
|
@ -6060,7 +6060,6 @@ export MOZ_ZLIB_CFLAGS
|
|||
export MOZ_ZLIB_LIBS
|
||||
export MOZ_APP_NAME
|
||||
export MOZ_APP_REMOTINGNAME
|
||||
export RUSTC
|
||||
export MOZILLA_CENTRAL_PATH=$_topsrcdir
|
||||
export STLPORT_CPPFLAGS
|
||||
export STLPORT_LIBS
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@ from ..frontend.data import (
|
|||
ObjdirPreprocessedFiles,
|
||||
PerSourceFlag,
|
||||
Program,
|
||||
RustLibrary,
|
||||
SharedLibrary,
|
||||
SimpleProgram,
|
||||
Sources,
|
||||
|
|
@ -574,12 +573,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
else:
|
||||
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):
|
||||
self._process_shared_library(obj, backend_file)
|
||||
self._process_linked_libraries(obj, backend_file)
|
||||
|
|
@ -1172,10 +1165,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
if libdef.no_expand_lib:
|
||||
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):
|
||||
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 write_shared_and_system_libs(lib):
|
||||
for l in lib.linked_libraries:
|
||||
if isinstance(l, (StaticLibrary, RustLibrary)):
|
||||
if isinstance(l, StaticLibrary):
|
||||
write_shared_and_system_libs(l)
|
||||
else:
|
||||
backend_file.write_once('SHARED_LIBS += %s/%s\n'
|
||||
|
|
@ -1208,11 +1197,7 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
self._build_target_for_obj(lib))
|
||||
relpath = pretty_relpath(lib)
|
||||
if isinstance(obj, Library):
|
||||
if isinstance(lib, RustLibrary):
|
||||
# We don't need to do anything here; we will handle
|
||||
# linkage for any RustLibrary elsewhere.
|
||||
continue
|
||||
elif isinstance(lib, StaticLibrary):
|
||||
if isinstance(lib, StaticLibrary):
|
||||
backend_file.write_once('STATIC_LIBS += %s/%s\n'
|
||||
% (relpath, lib.import_name))
|
||||
if isinstance(obj, SharedLibrary):
|
||||
|
|
@ -1235,12 +1220,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
backend_file.write_once('HOST_LIBS += %s/%s\n'
|
||||
% (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:
|
||||
if obj.KIND == 'target':
|
||||
backend_file.write_once('OS_LIBS += %s\n' % lib)
|
||||
|
|
@ -1250,23 +1229,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
# Process library-based defines
|
||||
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):
|
||||
target = obj.install_target
|
||||
path = mozpath.basedir(target, (
|
||||
|
|
@ -1445,11 +1407,6 @@ class RecursiveMakeBackend(CommonBackend):
|
|||
|
||||
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,
|
||||
unified_ipdl_cppsrcs_mapping):
|
||||
# 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"""
|
||||
|
||||
|
||||
class LinkageMultipleRustLibrariesError(Exception):
|
||||
"""Error thrown when trying to link multiple Rust libraries to an object"""
|
||||
|
||||
|
||||
class Linkable(ContextDerived):
|
||||
"""Generic context derived container object for programs and libraries"""
|
||||
__slots__ = (
|
||||
|
|
@ -337,13 +333,6 @@ class Linkable(ContextDerived):
|
|||
'Linkable.link_library() does not take components.')
|
||||
if 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)
|
||||
if obj.cxx_link:
|
||||
self.cxx_link = True
|
||||
|
|
@ -474,40 +463,6 @@ class StaticLibrary(Library):
|
|||
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):
|
||||
"""Context derived container object for a shared library"""
|
||||
__slots__ = (
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ from .data import (
|
|||
PreprocessedTestWebIDLFile,
|
||||
PreprocessedWebIDLFile,
|
||||
Program,
|
||||
RustLibrary,
|
||||
SdkFiles,
|
||||
SharedLibrary,
|
||||
SimpleProgram,
|
||||
|
|
@ -198,7 +197,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
def _emit_libs_derived(self, contexts):
|
||||
# First do FINAL_LIBRARY linkage.
|
||||
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
|
||||
if lib.link_into not in self._libs:
|
||||
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),
|
||||
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):
|
||||
linkables = []
|
||||
host_linkables = []
|
||||
|
|
@ -688,11 +627,7 @@ class TreeMetadataEmitter(LoggingMixin):
|
|||
'generate_symbols_file', lib.symbols_file,
|
||||
[symbols_file], defines)
|
||||
if static_lib:
|
||||
is_rust_library = context.get('IS_RUST_LIBRARY')
|
||||
if is_rust_library:
|
||||
lib = self._rust_library(context, libname, static_args)
|
||||
else:
|
||||
lib = StaticLibrary(context, libname, **static_args)
|
||||
lib = StaticLibrary(context, libname, **static_args)
|
||||
self._libs[libname].append(lib)
|
||||
self._linkage.append((context, lib, 'USE_LIBS'))
|
||||
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,
|
||||
LocalInclude,
|
||||
Program,
|
||||
RustLibrary,
|
||||
SdkFiles,
|
||||
SharedLibrary,
|
||||
SimpleProgram,
|
||||
|
|
@ -1021,78 +1020,6 @@ class TestEmitterBasic(unittest.TestCase):
|
|||
'Only source directory paths allowed in FINAL_TARGET_PP_FILES:'):
|
||||
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):
|
||||
"""Test that ANDROID_RES_DIRS works properly."""
|
||||
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